fix: unicode problems (archive downloads)

This commit is contained in:
Massimo Melina 2020-05-09 17:17:03 +02:00
parent edd0fada64
commit 6bf82353b8
3 changed files with 30 additions and 15 deletions

View File

@ -77,7 +77,7 @@ type
public public
flist: array of record flist: array of record
src, // full path of the file on the disk 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 firstByte, // offset of the file inside the archive
mtime, mtime,
size: int64; size: int64;
@ -87,7 +87,7 @@ type
constructor create; constructor create;
destructor Destroy; override; 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; function count():integer;
procedure reset(); virtual; procedure reset(); virtual;
property totalSize:int64 read getTotal; property totalSize:int64 read getTotal;
@ -417,7 +417,7 @@ if cachedTotal < 0 then calculate();
result:=cachedTotal; result:=cachedTotal;
end; // getTotal 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; function getMtime(fh:Thandle):int64;
var var
@ -565,10 +565,13 @@ const
PERM = '0100777'#0'0000000'#0'0000000'#0; // file mode, uid, gid PERM = '0100777'#0'0000000'#0'0000000'#0; // file mode, uid, gid
var var
fn, s, pre: ansistring; fn, s, pre: ansistring;
ufn: string;
begin begin
fn:=ansistring(replaceStr(flist[cur].dst,'\','/')); ufn:=replaceStr(flist[cur].dst,'\','/');
if fileNamesOEM then if fileNamesOEM then
CharToOem(pWideChar(string(fn)), pAnsiChar(fn)); CharToOem(pWideChar(ufn), pAnsiChar(fn))
else
fn:=UTF8encode(ufn);
pre:=''; pre:='';
if length(fn) >= 100 then if length(fn) >= 100 then
begin begin
@ -598,7 +601,8 @@ begin raise EWriteError.Create('write unsupproted') end;
function gap512(i:int64):word; inline; function gap512(i:int64):word; inline;
begin begin
result:=i and 511; result:=i and 511;
if result > 0 then result:=512-result; if result > 0 then
result:=512-result;
end; // gap512 end; // gap512
procedure TtarStream.padInit(full:boolean=FALSE); procedure TtarStream.padInit(full:boolean=FALSE);
@ -970,7 +974,7 @@ if (i < 0) and assigned(over) then
lastExt.section:=fileExt; lastExt.section:=fileExt;
lastExt.idx:=i; lastExt.idx:=i;
if i < 0 then exit; if i < 0 then exit;
i:=int_(fileExts[i+1]); i:=int_(ansistring(fileExts[i+1]));
lastExt.idx:=i; lastExt.idx:=i;
result:=sections[i].txt; result:=sections[i].txt;
end; // getTxtByExt end; // getTxtByExt

View File

@ -447,7 +447,7 @@ end; // nonQuotedPos
// consider using TBase64Encoding.Base64.Encode() in unit netencoding // consider using TBase64Encoding.Base64.Encode() in unit netencoding
function base64encode(s:ansistring):ansistring; function base64encode(s:ansistring):ansistring;
const const
TABLE='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; TABLE:ansistring='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
type type
Ttriple=array [0..2] of byte; Ttriple=array [0..2] of byte;
var var
@ -464,9 +464,15 @@ for i:=1 to length(s) div 3 do
+TABLE[1+(p[2] and 63)]; +TABLE[1+(p[2] and 63)];
inc(p); inc(p);
end; end;
if length(s) mod 3 > 0 then 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] exit;
+ifThen(length(s) mod 3=1,'==',TABLE[1+(p[1] and 15) shl 2+p[2] shr 6]+'='); 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 end; // base64encode
function base64decode(s:ansistring):ansistring; function base64decode(s:ansistring):ansistring;

View File

@ -4806,8 +4806,11 @@ var
end; // getUploadDestinationFileName end; // getUploadDestinationFileName
procedure addContentDisposition(attach:boolean=TRUE); procedure addContentDisposition(attach:boolean=TRUE);
var s:ansistring;
begin 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; end;
procedure sessionSetup(); procedure sessionSetup();
@ -4890,13 +4893,14 @@ var
if sameText('selection', data.postvars.names[i]) then if sameText('selection', data.postvars.names[i]) then
begin begin
selection:=TRUE; selection:=TRUE;
s:=decodeURL(getTill('#', data.postvars.valueFromIndex[i])); // omit #anchors s:=getTill('#', data.postvars.valueFromIndex[i]); // omit #anchors
if dirCrossing(s) then continue; if dirCrossing(s) then continue;
ft:=findFilebyURL(s, f); ft:=findFilebyURL(s, f);
if ft = NIL then continue; if ft = NIL then continue;
try try
if not ft.accessFor(data) then continue; if not ft.accessFor(data) then
continue;
// case folder // case folder
if ft.isFolder() then if ft.isFolder() then
begin begin
@ -4904,7 +4908,8 @@ var
continue; continue;
end; end;
// case file // case file
if not fileExists(ft.resource) then continue; if not fileExists(ft.resource) then
continue;
if noFolders then if noFolders then
s:=substr(s, lastDelimiter('\/', s)+1); s:=substr(s, lastDelimiter('\/', s)+1);
tar.addFile(ft.resource, s); tar.addFile(ft.resource, s);