Browse Source

* Fix bug ID #32656: arbitrary limit on chunk size.

git-svn-id: trunk@37849 -
michael 7 years ago
parent
commit
9d7d95fe25
1 changed files with 11 additions and 4 deletions
  1. 11 4
      packages/fcl-web/src/base/fphttpclient.pp

+ 11 - 4
packages/fcl-web/src/base/fphttpclient.pp

@@ -71,6 +71,7 @@ Type
     FContentLength : Int64;
     FContentLength : Int64;
     FAllowRedirect: Boolean;
     FAllowRedirect: Boolean;
     FKeepConnection: Boolean;
     FKeepConnection: Boolean;
+    FMaxChunkSize: SizeUInt;
     FMaxRedirects: Byte;
     FMaxRedirects: Byte;
     FOnDataReceived: TDataEvent;
     FOnDataReceived: TDataEvent;
     FOnHeaders: TNotifyEvent;
     FOnHeaders: TNotifyEvent;
@@ -295,6 +296,9 @@ Type
     Property AllowRedirect : Boolean Read FAllowRedirect Write FAllowRedirect;
     Property AllowRedirect : Boolean Read FAllowRedirect Write FAllowRedirect;
     // Maximum number of redirects. When this number is reached, an exception is raised.
     // Maximum number of redirects. When this number is reached, an exception is raised.
     Property MaxRedirects : Byte Read FMaxRedirects Write FMaxRedirects default DefMaxRedirects;
     Property MaxRedirects : Byte Read FMaxRedirects Write FMaxRedirects default DefMaxRedirects;
+    // Maximum chunk size: If chunk sizes bigger than this are encountered, an error will be raised.
+    // Set to zero to disable the check.
+    Property MaxChunkSize : SizeUInt Read FMaxChunkSize Write FMaxChunkSize;
     // Called On redirect. Dest URL can be edited.
     // Called On redirect. Dest URL can be edited.
     // If The DEST url is empty on return, the method is aborted (with redirect status).
     // If The DEST url is empty on return, the method is aborted (with redirect status).
     Property OnRedirect : TRedirectEvent Read FOnRedirect Write FOnRedirect;
     Property OnRedirect : TRedirectEvent Read FOnRedirect Write FOnRedirect;
@@ -363,7 +367,7 @@ resourcestring
   SErrInvalidProtocolVersion = 'Invalid protocol version in response: "%s"';
   SErrInvalidProtocolVersion = 'Invalid protocol version in response: "%s"';
   SErrInvalidStatusCode = 'Invalid response status code: %s';
   SErrInvalidStatusCode = 'Invalid response status code: %s';
   SErrUnexpectedResponse = 'Unexpected response status code: %d';
   SErrUnexpectedResponse = 'Unexpected response status code: %d';
-  SErrChunkTooBig = 'Chunk too big';
+  SErrChunkTooBig = 'Chunk too big: Got %d, maximum allowed size: %d';
   SErrChunkLineEndMissing = 'Chunk line end missing';
   SErrChunkLineEndMissing = 'Chunk line end missing';
   SErrMaxRedirectsReached = 'Maximum allowed redirects reached : %d';
   SErrMaxRedirectsReached = 'Maximum allowed redirects reached : %d';
   //SErrRedirectAborted = 'Redirect aborted.';
   //SErrRedirectAborted = 'Redirect aborted.';
@@ -1038,7 +1042,7 @@ Function TFPCustomHTTPClient.ReadResponse(Stream: TStream;
 
 
   var
   var
     c: char;
     c: char;
-    ChunkSize: Integer;
+    ChunkSize: SizeUInt;
     l: Integer;
     l: Integer;
   begin
   begin
     BufPos:=1;
     BufPos:=1;
@@ -1047,6 +1051,9 @@ Function TFPCustomHTTPClient.ReadResponse(Stream: TStream;
       ChunkSize:=0;
       ChunkSize:=0;
       repeat
       repeat
         if ReadData(@c,1)<1 then exit;
         if ReadData(@c,1)<1 then exit;
+        // Protect from overflow
+        If ChunkSize>(High(SizeUInt) div 16) then
+          Raise EHTTPClient.CreateFmt(SErrChunkTooBig,[ChunkSize,High(SizeUInt) div 16]);
         case c of
         case c of
         '0'..'9': ChunkSize:=ChunkSize*16+ord(c)-ord('0');
         '0'..'9': ChunkSize:=ChunkSize*16+ord(c)-ord('0');
         'a'..'f': ChunkSize:=ChunkSize*16+ord(c)-ord('a')+10;
         'a'..'f': ChunkSize:=ChunkSize*16+ord(c)-ord('a')+10;
@@ -1054,8 +1061,8 @@ Function TFPCustomHTTPClient.ReadResponse(Stream: TStream;
         else
         else
           break;
           break;
         end;
         end;
-        if ChunkSize>1000000 then
-          Raise EHTTPClient.Create(SErrChunkTooBig);
+        If (MaxChunkSize>0) and (ChunkSize>MaxChunkSize) then
+          Raise EHTTPClient.CreateFmt(SErrChunkTooBig,[ChunkSize,MaxChunkSize]);
       until Terminated;
       until Terminated;
       // read till line end
       // read till line end
       while (c<>#10) and not Terminated do
       while (c<>#10) and not Terminated do