From 6bf82353b8748ef0eb88b5373e57930a3398e22b Mon Sep 17 00:00:00 2001 From: Massimo Melina Date: Sat, 9 May 2020 17:17:03 +0200 Subject: [PATCH] fix: unicode problems (archive downloads) --- classesLib.pas | 18 +++++++++++------- hslib.pas | 14 ++++++++++---- main.pas | 13 +++++++++---- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/classesLib.pas b/classesLib.pas index c815dd5..baeaee1 100644 --- a/classesLib.pas +++ b/classesLib.pas @@ -77,7 +77,7 @@ TarchiveStream = class(Tstream) public flist: array of record src, // full path of the file on the disk - dst: ansistring; // full path of the file in the archive + dst: string; // full path of the file in the archive firstByte, // offset of the file inside the archive mtime, size: int64; @@ -87,7 +87,7 @@ TarchiveStream = class(Tstream) constructor create; destructor Destroy; override; - function addFile(src:ansistring; dst:ansistring=''; data:Tobject=NIL):boolean; virtual; + function addFile(src:string; dst:string=''; data:Tobject=NIL):boolean; virtual; function count():integer; procedure reset(); virtual; property totalSize:int64 read getTotal; @@ -417,7 +417,7 @@ function TarchiveStream.getTotal():int64; result:=cachedTotal; end; // getTotal -function TarchiveStream.addFile(src:ansistring; dst:ansistring=''; data:Tobject=NIL):boolean; +function TarchiveStream.addFile(src:string; dst:string=''; data:Tobject=NIL):boolean; function getMtime(fh:Thandle):int64; var @@ -565,10 +565,13 @@ procedure TtarStream.headerInit(); PERM = '0100777'#0'0000000'#0'0000000'#0; // file mode, uid, gid var fn, s, pre: ansistring; + ufn: string; begin -fn:=ansistring(replaceStr(flist[cur].dst,'\','/')); +ufn:=replaceStr(flist[cur].dst,'\','/'); if fileNamesOEM then - CharToOem(pWideChar(string(fn)), pAnsiChar(fn)); + CharToOem(pWideChar(ufn), pAnsiChar(fn)) +else + fn:=UTF8encode(ufn); pre:=''; if length(fn) >= 100 then begin @@ -598,7 +601,8 @@ function TtarStream.write(const Buffer; Count: Longint): Longint; function gap512(i:int64):word; inline; begin result:=i and 511; -if result > 0 then result:=512-result; +if result > 0 then + result:=512-result; end; // gap512 procedure TtarStream.padInit(full:boolean=FALSE); @@ -970,7 +974,7 @@ function Ttpl.getTxtByExt(fileExt:string):string; lastExt.section:=fileExt; lastExt.idx:=i; if i < 0 then exit; -i:=int_(fileExts[i+1]); +i:=int_(ansistring(fileExts[i+1])); lastExt.idx:=i; result:=sections[i].txt; end; // getTxtByExt diff --git a/hslib.pas b/hslib.pas index 18b539e..53d01e5 100644 --- a/hslib.pas +++ b/hslib.pas @@ -447,7 +447,7 @@ function nonQuotedPos(ss, s:string; ofs:integer=1; quote:string='"'; unquote:str // consider using TBase64Encoding.Base64.Encode() in unit netencoding function base64encode(s:ansistring):ansistring; const - TABLE='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + TABLE:ansistring='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; type Ttriple=array [0..2] of byte; var @@ -464,9 +464,15 @@ function base64encode(s:ansistring):ansistring; +TABLE[1+(p[2] and 63)]; inc(p); end; -if length(s) mod 3 > 0 then - result:=result+TABLE[1+p[0] shr 2]+TABLE[1+(p[0] and 3) shl 4+p[1] shr 4] - +ifThen(length(s) mod 3=1,'==',TABLE[1+(p[1] and 15) shl 2+p[2] shr 6]+'='); +if length(s) mod 3 = 0 then + exit; +result:=result + +TABLE[1+p[0] shr 2] + +TABLE[1+(p[0] and 3) shl 4+p[1] shr 4]; +if length(s) mod 3=1 then + result:=result+'==' +else + result:=result+TABLE[1+(p[1] and 15) shl 2+p[2] shr 6]+'='; end; // base64encode function base64decode(s:ansistring):ansistring; diff --git a/main.pas b/main.pas index 4684721..717daa0 100644 --- a/main.pas +++ b/main.pas @@ -4806,8 +4806,11 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); end; // getUploadDestinationFileName procedure addContentDisposition(attach:boolean=TRUE); + var s:ansistring; begin - conn.addHeader( 'Content-Disposition: '+if_(attach, 'attachment; ')+'filename*=UTF-8''"'+UTF8encode(data.lastFN)+'";'); + s:=HSlib.encodeURL(data.lastFN); + conn.addHeader( 'Content-Disposition: '+if_(attach, 'attachment; ') + +'filename*=UTF-8'''''+s+'; filename='+s); end; procedure sessionSetup(); @@ -4890,13 +4893,14 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); if sameText('selection', data.postvars.names[i]) then begin selection:=TRUE; - s:=decodeURL(getTill('#', data.postvars.valueFromIndex[i])); // omit #anchors + s:=getTill('#', data.postvars.valueFromIndex[i]); // omit #anchors if dirCrossing(s) then continue; ft:=findFilebyURL(s, f); if ft = NIL then continue; try - if not ft.accessFor(data) then continue; + if not ft.accessFor(data) then + continue; // case folder if ft.isFolder() then begin @@ -4904,7 +4908,8 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); continue; end; // case file - if not fileExists(ft.resource) then continue; + if not fileExists(ft.resource) then + continue; if noFolders then s:=substr(s, lastDelimiter('\/', s)+1); tar.addFile(ft.resource, s);