mirror of
https://github.com/rejetto/hfs2.git
synced 2025-12-19 10:03:56 +01:00
fix: unicode problems (file upload)
This commit is contained in:
parent
b49c15d043
commit
09abf511ea
23
hslib.pas
23
hslib.pas
@ -32,7 +32,7 @@ uses
|
|||||||
OverbyteIcsWSocket, classes, messages, winprocs, forms, extctrls, sysutils, contnrs, strUtils, winsock, inifiles, types;
|
OverbyteIcsWSocket, classes, messages, winprocs, forms, extctrls, sysutils, contnrs, strUtils, winsock, inifiles, types;
|
||||||
|
|
||||||
const
|
const
|
||||||
VERSION = '2.10.1';
|
VERSION = '2.11.0';
|
||||||
|
|
||||||
type
|
type
|
||||||
ThttpSrv=class;
|
ThttpSrv=class;
|
||||||
@ -125,7 +125,7 @@ type
|
|||||||
length: int64; // multipart form-data length
|
length: int64; // multipart form-data length
|
||||||
boundary, // multipart form-data boundary
|
boundary, // multipart form-data boundary
|
||||||
header, // contextual header
|
header, // contextual header
|
||||||
data, // misc data
|
data: ansistring; // misc data
|
||||||
varname, // post variable name
|
varname, // post variable name
|
||||||
filename: string; // name of posted file
|
filename: string; // name of posted file
|
||||||
mode: (PM_NONE, PM_URLENCODED, PM_MULTIPART);
|
mode: (PM_NONE, PM_URLENCODED, PM_MULTIPART);
|
||||||
@ -1168,7 +1168,8 @@ procedure ThttpConn.processInputBuffer();
|
|||||||
{ only about the data we are sure it doesn't overlap a possibly coming boundary }
|
{ only about the data we are sure it doesn't overlap a possibly coming boundary }
|
||||||
begin
|
begin
|
||||||
post.data:=chop(length(buffer)-length(post.boundary), 0, buffer);
|
post.data:=chop(length(buffer)-length(post.boundary), 0, buffer);
|
||||||
if post.data > '' then tryNotify(HE_POST_MORE_FILE);
|
if post.data > ''
|
||||||
|
then tryNotify(HE_POST_MORE_FILE);
|
||||||
end;
|
end;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -1202,8 +1203,8 @@ procedure ThttpConn.processInputBuffer();
|
|||||||
while l > '' do
|
while l > '' do
|
||||||
begin
|
begin
|
||||||
c:=chop(nonQuotedPos(';', l), l);
|
c:=chop(nonQuotedPos(';', l), l);
|
||||||
k:=trim(chop('=', c));
|
k:=UTF8decode(trim(chop('=', c)));
|
||||||
c:=ansiDequotedStr(c,'"');
|
c:=UTF8decode(ansiDequotedStr(c,'"'));
|
||||||
if sameText(k, 'filename') then
|
if sameText(k, 'filename') then
|
||||||
begin
|
begin
|
||||||
delete(c, 1, lastDelimiter('/\',c));
|
delete(c, 1, lastDelimiter('/\',c));
|
||||||
@ -1355,18 +1356,20 @@ var
|
|||||||
s: string;
|
s: string;
|
||||||
begin
|
begin
|
||||||
if error <> 0 then exit;
|
if error <> 0 then exit;
|
||||||
s:=sock.ReceiveStr();
|
s:=sock.ReceiveStrA();
|
||||||
inc(brecvd, length(s));
|
inc(brecvd, length(s));
|
||||||
inc(srv.brecvd, length(s));
|
inc(srv.brecvd, length(s));
|
||||||
if (s = '') or dontFulFil then exit;
|
if (s = '') or dontFulFil then
|
||||||
if state = HCS_POSTING then inc(postDataReceived, length(s));
|
exit;
|
||||||
buffer:=buffer+s;
|
if state = HCS_POSTING then
|
||||||
if length(buffer) > MAX_INPUT_BUFFER_LENGTH then
|
inc(postDataReceived, length(s));
|
||||||
|
if length(buffer)+length(s) > MAX_INPUT_BUFFER_LENGTH then
|
||||||
begin
|
begin
|
||||||
disconnect();
|
disconnect();
|
||||||
try sock.Abort() except end; // please, brutally
|
try sock.Abort() except end; // please, brutally
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
buffer:=buffer+s;
|
||||||
eventData:=s;
|
eventData:=s;
|
||||||
notify(HE_GOT);
|
notify(HE_GOT);
|
||||||
processInputBuffer();
|
processInputBuffer();
|
||||||
|
|||||||
29
main.pas
29
main.pas
@ -1122,7 +1122,6 @@ var
|
|||||||
stopAddingItems, queryingClose: boolean;
|
stopAddingItems, queryingClose: boolean;
|
||||||
port: string;
|
port: string;
|
||||||
defaultTpl: string;
|
defaultTpl: string;
|
||||||
tpl_help: string;
|
|
||||||
lastWindowRect: Trect;
|
lastWindowRect: Trect;
|
||||||
dmBrowserTpl, filelistTpl: Ttpl;
|
dmBrowserTpl, filelistTpl: Ttpl;
|
||||||
tplEditor: string;
|
tplEditor: string;
|
||||||
@ -4397,7 +4396,7 @@ try
|
|||||||
lastPath:=path;
|
lastPath:=path;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
trancheEnd:=length(files)-1; // after the for-loop, the variable seems to not be trustable
|
trancheEnd:=length(files)-1; // after the for-loop, the variable seems to not be reliable
|
||||||
doTheTranche();
|
doTheTranche();
|
||||||
finally ss.free end;
|
finally ss.free end;
|
||||||
end; // removeFilesFromComments
|
end; // removeFilesFromComments
|
||||||
@ -4712,7 +4711,7 @@ var
|
|||||||
|
|
||||||
procedure extractParams();
|
procedure extractParams();
|
||||||
var
|
var
|
||||||
s: ansistring;
|
s: string;
|
||||||
i: integer;
|
i: integer;
|
||||||
begin
|
begin
|
||||||
s:=url;
|
s:=url;
|
||||||
@ -5586,7 +5585,8 @@ if assigned(conn) and (conn.getLockCount <> 1) then
|
|||||||
|
|
||||||
f:=NIL;
|
f:=NIL;
|
||||||
data:=NIL;
|
data:=NIL;
|
||||||
if assigned(conn) then data:=conn.data;
|
if assigned(conn) then
|
||||||
|
data:=conn.data;
|
||||||
if assigned(data) then
|
if assigned(data) then
|
||||||
data.lastActivityTime:=now();
|
data.lastActivityTime:=now();
|
||||||
|
|
||||||
@ -5719,7 +5719,7 @@ case event of
|
|||||||
data.fileXferStart:=now();
|
data.fileXferStart:=now();
|
||||||
f:=findFileByURL(decodeURL(conn.request.url));
|
f:=findFileByURL(decodeURL(conn.request.url));
|
||||||
data.lastFile:=f; // auto-freeing
|
data.lastFile:=f; // auto-freeing
|
||||||
data.uploadSrc:=optAnsi(tpl.utf8, conn.post.filename);
|
data.uploadSrc:=conn.post.filename;
|
||||||
data.uploadFailed:='';
|
data.uploadFailed:='';
|
||||||
if (f = NIL) or not accountAllowed(FA_UPLOAD, data, f) or not f.accessFor(data) then
|
if (f = NIL) or not accountAllowed(FA_UPLOAD, data, f) or not f.accessFor(data) then
|
||||||
data.uploadFailed:=if_(f=NIL, 'Folder not found.', 'Not allowed.')
|
data.uploadFailed:=if_(f=NIL, 'Folder not found.', 'Not allowed.')
|
||||||
@ -6311,6 +6311,12 @@ port:=was;
|
|||||||
if act then startServer();
|
if act then startServer();
|
||||||
end; // changePort
|
end; // changePort
|
||||||
|
|
||||||
|
function b64utf8(const s:string):ansistring;
|
||||||
|
begin result:=base64encode(UTF8encode(s)); end;
|
||||||
|
|
||||||
|
function decodeB64utf8(const s:ansistring):string;
|
||||||
|
begin result:=UTF8decode(base64decode(s)); end;
|
||||||
|
|
||||||
function zCompressStr(const s: ansistring; level:TCompressionLevel=clMax; type_:TzStreamType=zsZlib): ansistring;
|
function zCompressStr(const s: ansistring; level:TCompressionLevel=clMax; type_:TzStreamType=zsZlib): ansistring;
|
||||||
var
|
var
|
||||||
src, dst: TMemoryStream;
|
src, dst: TMemoryStream;
|
||||||
@ -6489,7 +6495,7 @@ result:='HFS '+VERSION+' - Build #'+VERSION_BUILD+CRLF
|
|||||||
+'custom-ip='+join(';',customIPs)+CRLF
|
+'custom-ip='+join(';',customIPs)+CRLF
|
||||||
+'listen-on='+listenOn+CRLF
|
+'listen-on='+listenOn+CRLF
|
||||||
+'external-ip-server='+customIPservice+CRLF
|
+'external-ip-server='+customIPservice+CRLF
|
||||||
+'dynamic-dns-updater='+base64encode(dyndns.url)+CRLF
|
+'dynamic-dns-updater='+b64utf8(dyndns.url)+CRLF
|
||||||
+'dynamic-dns-user='+dyndns.user+CRLF
|
+'dynamic-dns-user='+dyndns.user+CRLF
|
||||||
+'dynamic-dns-host='+dyndns.host+CRLF
|
+'dynamic-dns-host='+dyndns.host+CRLF
|
||||||
+'search-better-ip='+yesno[searchbetteripChk.checked]+CRLF
|
+'search-better-ip='+yesno[searchbetteripChk.checked]+CRLF
|
||||||
@ -6835,7 +6841,7 @@ while cfg > '' do
|
|||||||
if h = 'ip' then savedip:=l;
|
if h = 'ip' then savedip:=l;
|
||||||
if h = 'custom-ip' then customIPs:=split(';',l);
|
if h = 'custom-ip' then customIPs:=split(';',l);
|
||||||
if h = 'listen-on' then listenOn:=l;
|
if h = 'listen-on' then listenOn:=l;
|
||||||
if h = 'dynamic-dns-updater' then dyndns.url:=base64decode(l);
|
if h = 'dynamic-dns-updater' then dyndns.url:=decodeB64utf8(l);
|
||||||
if h = 'dynamic-dns-user' then dyndns.user:=l;
|
if h = 'dynamic-dns-user' then dyndns.user:=l;
|
||||||
if h = 'dynamic-dns-host' then dyndns.host:=l;
|
if h = 'dynamic-dns-host' then dyndns.host:=l;
|
||||||
if h = 'login-realm' then loginRealm:=l;
|
if h = 'login-realm' then loginRealm:=l;
|
||||||
@ -9219,7 +9225,7 @@ f:=nodeToFile(node);
|
|||||||
commonFields:=TLV(FK_FLAGS, str_(f.flags))
|
commonFields:=TLV(FK_FLAGS, str_(f.flags))
|
||||||
+TLV_NOT_EMPTY(FK_RESOURCE, f.resource)
|
+TLV_NOT_EMPTY(FK_RESOURCE, f.resource)
|
||||||
+TLV_NOT_EMPTY(FK_COMMENT, f.comment)
|
+TLV_NOT_EMPTY(FK_COMMENT, f.comment)
|
||||||
+if_(f.user>'', TLV(FK_USERPWD_UTF8, base64encode(f.user+':'+f.pwd)))
|
+if_(f.user>'', TLV(FK_USERPWD_UTF8, b64utf8(f.user+':'+f.pwd)))
|
||||||
+TLV_NOT_EMPTY(FK_ACCOUNTS, join(';',f.accounts[FA_ACCESS]) )
|
+TLV_NOT_EMPTY(FK_ACCOUNTS, join(';',f.accounts[FA_ACCESS]) )
|
||||||
+TLV_NOT_EMPTY(FK_UPLOADACCOUNTS, join(';',f.accounts[FA_UPLOAD]))
|
+TLV_NOT_EMPTY(FK_UPLOADACCOUNTS, join(';',f.accounts[FA_UPLOAD]))
|
||||||
+TLV_NOT_EMPTY(FK_DELETEACCOUNTS, join(';',f.accounts[FA_DELETE]))
|
+TLV_NOT_EMPTY(FK_DELETEACCOUNTS, join(';',f.accounts[FA_DELETE]))
|
||||||
@ -9380,7 +9386,7 @@ while not tlv.isOver() do
|
|||||||
end;
|
end;
|
||||||
FK_USERPWD_UTF8:
|
FK_USERPWD_UTF8:
|
||||||
begin
|
begin
|
||||||
s:=UTF8toString(base64decode(data));
|
s:=decodeB64utf8(data);
|
||||||
f.user:=chop(':',s);
|
f.user:=chop(':',s);
|
||||||
f.pwd:=s;
|
f.pwd:=s;
|
||||||
usersInVFS.track(f.user, f.pwd);
|
usersInVFS.track(f.user, f.pwd);
|
||||||
@ -12132,7 +12138,7 @@ while current > '' do
|
|||||||
if defV = v then continue;
|
if defV = v then continue;
|
||||||
if k = 'dynamic-dns-updater' then
|
if k = 'dynamic-dns-updater' then
|
||||||
begin // remove login data
|
begin // remove login data
|
||||||
v:=base64decode(v);
|
v:=decodeB64utf8(v);
|
||||||
chop('//',v);
|
chop('//',v);
|
||||||
v:=chop('/',v);
|
v:=chop('/',v);
|
||||||
if ansiContainsStr(v, '@') then chop('@',v);
|
if ansiContainsStr(v, '@') then chop('@',v);
|
||||||
@ -12411,7 +12417,6 @@ if fileExists('default.tpl') then
|
|||||||
defaultTpl:=loadTextfile('default.tpl')
|
defaultTpl:=loadTextfile('default.tpl')
|
||||||
else
|
else
|
||||||
defaultTpl:=getRes('defaultTpl');
|
defaultTpl:=getRes('defaultTpl');
|
||||||
tpl_help:=getRes('tplHlp');
|
|
||||||
tpl:=Ttpl.create();
|
tpl:=Ttpl.create();
|
||||||
defSorting:='name';
|
defSorting:='name';
|
||||||
dmBrowserTpl:=Ttpl.create(getRes('dmBrowserTpl'));
|
dmBrowserTpl:=Ttpl.create(getRes('dmBrowserTpl'));
|
||||||
@ -12428,7 +12433,7 @@ logMaxLines:=2000;
|
|||||||
trayShows:='downloads';
|
trayShows:='downloads';
|
||||||
flashOn:='download';
|
flashOn:='download';
|
||||||
forwardedMask:='127.0.0.1';
|
forwardedMask:='127.0.0.1';
|
||||||
runningOnRemovable:=DRIVE_REMOVABLE = GetDriveTypeA(PansiChar(ansistring(exePath[1]+':\')));
|
runningOnRemovable:=DRIVE_REMOVABLE = GetDriveType(Pchar(exePath[1]+':\'));
|
||||||
etags.values['exe']:=strMD5(dateToHTTP(getMtimeUTC(paramStr(0))));
|
etags.values['exe']:=strMD5(dateToHTTP(getMtimeUTC(paramStr(0))));
|
||||||
|
|
||||||
dll:=GetModuleHandle('kernel32.dll');
|
dll:=GetModuleHandle('kernel32.dll');
|
||||||
|
|||||||
@ -2045,15 +2045,8 @@ try
|
|||||||
else
|
else
|
||||||
result:=intToStr(parI(0)+random(1+parI(1)-parI(0)));
|
result:=intToStr(parI(0)+random(1+parI(1)-parI(0)));
|
||||||
|
|
||||||
if name = 'force ansi' then
|
if (name = 'force ansi') or (name = 'maybe utf8') then // pre-unicode legacy
|
||||||
if satisfied(md.tpl) and md.tpl.utf8 then
|
result:=p;
|
||||||
result:=noMacrosAllowed(UTF8toAnsi(p))
|
|
||||||
else
|
|
||||||
result:=p;
|
|
||||||
|
|
||||||
if name = 'maybe utf8' then // pre-unicode legacy
|
|
||||||
if satisfied(md.tpl) then
|
|
||||||
result:=p;
|
|
||||||
|
|
||||||
if name = 'after the list' then
|
if name = 'after the list' then
|
||||||
if md.afterTheList then
|
if md.afterTheList then
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user