From 384d2d10f437d2cd34f88888a39a98b77e382b1c Mon Sep 17 00:00:00 2001 From: Massimo Melina Date: Sun, 3 May 2020 16:27:01 +0200 Subject: [PATCH] fix: presenting and serving unicode file names --- .gitignore | 7 +++++-- hfs.identcache | Bin 745 -> 0 bytes hfs.vrc | Bin 2072 -> 0 bytes hslib.pas | 9 ++++++--- main.pas | 21 +++++++++++++-------- 5 files changed, 24 insertions(+), 13 deletions(-) delete mode 100644 hfs.identcache delete mode 100644 hfs.vrc diff --git a/.gitignore b/.gitignore index 4f2fd81..4151b6f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,12 +2,15 @@ tmp/ __history/ __recovery/ win32/ +.vscode/ *.vfs *.dcu *.exe *.map -hfs.ini *.tmp *.bak *.*- -*.corrupted \ No newline at end of file +*.corrupted +hfs.ini +hfs.identcache + diff --git a/hfs.identcache b/hfs.identcache deleted file mode 100644 index 6a681d818e0383f2e8db695c1d5529e0bb84b87f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 745 zcma))J&pn~3`XY)bgabB0zC(y1*+YScA8=043Diy{Nz*jz z{jTkEfcAo)xyS&Ha%srSBj)4M8}8cwO321;|U0Q4}Suc CHOgfG diff --git a/hfs.vrc b/hfs.vrc deleted file mode 100644 index ab96e4db8e36592ff5643e86845fe8b4e3c71a7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2072 zcmb7_TW^~%6vy|B#CNc=Jyl)GCEexG0n=F}fWV=fGzqbUbVv=UNUCkB_T6`EjKi&y z>Vy#NpZ_^GpIlv__k5r<$x;$0Gz{k3Utal8cn|sgQ7&Fw>Dt?Eu`8>BgPxbUWVyaU z-C_JTnqm4wIEqP3e1a3wZcwl_hB0%#5Vs}auHeNOj%kV+*g}1|L&2X$Fb%vAE)vJB zd<&b#2u>p6Q0z}ATO*ie9`%XmR|MV=-0!9(zUk1B|0cR>b)xi~t+@fdkm}{WB%MDYzF44#(-sa4!}Bd*S#1 zDCJ&C08YPldtCD)3cl_Z62J+=j5?W5muG7f{81E=iDdugZBEyCN0JlByhKLx*0m@O z-L=D}mikRh^!Y(&Yhl)aB!;JXEtwgl0c?$M29+eu)iTHZAI7 z%b9b7zb4tJK5U;hry$=K|J9V-D`fBMd{12=x;gCU#r{WLZ}M$XALc{D|AM>xk}*p2 zdK4fT23F_Q@gbKXFb&(jM5c9Zy=fFcMAufB2Gj`yBtCeQGP*fb=DghSfSbr#h}g~F g?enVK6~`0IMm}a<7_S(PZwO0J?6{a=^lXCUKfPk@?f?J) diff --git a/hslib.pas b/hslib.pas index 636658d..25f83c1 100644 --- a/hslib.pas +++ b/hslib.pas @@ -102,6 +102,7 @@ ThttpReply = record RBM_STREAM // refer to bodyStream ); body: ansistring; // specifies reply body according to bodyMode + bodyFile: string; bodyStream: Tstream; // note: the stream is automatically freed firstByte, lastByte: int64; // body interval for partial replies (206) realm: ansistring; // this will appear in the authentication dialog @@ -528,7 +529,9 @@ function decodeURL(url:ansistring; utf8:boolean=TRUE):string; try url[j]:=ansichar(strToInt( '$'+url[i+1]+url[i+2] )); inc(i,2); // three chars for one - except url[j]:='_' end; + except url[j]:='_' end + else if i>j then + url[j]:=url[i]; end; setLength(url, j); if utf8 then @@ -1425,7 +1428,7 @@ procedure ThttpConn.datasent(sender:Tobject; error:word); reply.bodyMode:=RBM_STRING; reply.body:=HRM2BODY[reply.mode]; if reply.mode in [HRM_REDIRECT, HRM_MOVED] then - reply.body:=stringReplace(reply.body, '%url%', reply.url, [rfReplaceAll]); + reply.body:=replaceStr(reply.body, '%url%', reply.url); initInputStream(); end; end; @@ -1502,7 +1505,7 @@ function ThttpConn.initInputStream():boolean; end; RBM_FILE: begin - i:=fileopen(reply.body, fmOpenRead+fmShareDenyNone); + i:=fileopen(reply.bodyFile, fmOpenRead+fmShareDenyNone); if i = -1 then exit; stream:=TFileStream.Create(i); end; diff --git a/main.pas b/main.pas index 5d738dd..e759123 100644 --- a/main.pas +++ b/main.pas @@ -1330,7 +1330,7 @@ function hasRightAttributes(attr:integer):boolean; overload; end; // hasRightAttributes function hasRightAttributes(fn:string):boolean; overload; -begin result:=hasRightAttributes(GetFileAttributesA(pAnsiChar(ansiString(fn)))) end; +begin result:=hasRightAttributes(GetFileAttributes(pChar(fn))) end; function isAnyMacroIn(s:ansistring):boolean; inline; begin result:=pos(MARKER_OPEN, s) > 0 end; @@ -3242,7 +3242,7 @@ function Tmainfrm.findFilebyURL(url:string; parent:Tfile=NIL; allowTemp:boolean= n:=cur.getFirstChild(); while assigned(n) do begin - found:=stringExists(n.text, s) or sameText(n.text, UTF8toString(s)); + found:=sameText(n.text, s); if found then break; n:=n.getNextSibling(); end; @@ -3556,7 +3556,7 @@ function Tmainfrm.getFolderPage(folder:Tfile; cd:TconnData; otpl:Tobject):string diffTpl.fullText:=optUTF8(diffTpl.over, folder.getRecursiveDiffTplAsStr()); isDMbrowser:= otpl = dmBrowserTpl; - fullEncode:=not isDMbrowser; + fullEncode:=FALSE; ofsRelUrl:=length(folder.url(fullEncode))+1; ofsRelItemUrl:=length(optUTF8(diffTpl, folder.pathTill()))+1; // pathTill() is '/' for root, and 'just/folder', so we must accordingly consider a starting and trailing '/' for the latter case (bugfix by mars) @@ -4478,7 +4478,7 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); var data: TconnData; f: Tfile; - url: ansistring; + url: string; procedure switchToDefaultFile(); var @@ -4801,6 +4801,11 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); assignFile(data.f^, data.uploadDest); end; // getUploadDestinationFileName + procedure addContentDisposition(attach:boolean=TRUE); + begin + conn.addHeader( 'Content-Disposition: '+if_(attach, 'attachment; ')+'filename*=UTF-8''"'+UTF8encode(data.lastFN)+'";'); + end; + procedure sessionSetup(); begin if (data = NIL) or assigned(data.session) then exit; @@ -4948,7 +4953,7 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); '%archive-size%', intToStr(tar.size) ]), data.lastFN); if not noContentdispositionChk.checked then - conn.addHeader('Content-Disposition: attachment; filename="'+data.lastFN+'";'); + addContentDisposition(); except tar.free end; end; // serveTar @@ -5029,7 +5034,7 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); conn.reply.contentType:=if_(trim(getTill('<', s))='', 'text/html', 'text/plain'); conn.reply.mode:=HRM_REPLY; conn.reply.bodyMode:=RBM_STRING; - conn.reply.body:=s; + conn.reply.body:=UTF8encode(s); compressReply(data); end; // replyWithString @@ -5474,7 +5479,7 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); data.eta.idx:=0; conn.reply.contentType:=name2mimetype(f.name, DEFAULT_MIME); conn.reply.bodyMode:=RBM_FILE; - conn.reply.body:=f.resource; + conn.reply.bodyFile:=f.resource; data.downloadingWhat:=DW_FILE; { I guess this would not help in any way for files since we are already handling the 'if-modified-since' field try @@ -5493,7 +5498,7 @@ procedure Tmainfrm.httpEvent(event:ThttpEvent; conn:ThttpConn); if (data.agent = 'MSIE') and (conn.getHeader('Accept') = '*/*') then s:=replaceStr(s, ' ','%20'); if not noContentdispositionChk.checked or not b then - conn.addHeader( 'Content-Disposition: '+if_(not b, 'attachment; ')+'filename="'+s+'";' ); + addContentDisposition(not b); end; // handleRequest procedure lastByte();