@@ -381,11 +381,14 @@ class function TNetwork.WebRequest(AMethod: TWebMethod; const AUrl: string; cons
381381 if SameText(contentEncoding, ' gzip' ) and IsGzip(rawStream) then
382382 begin
383383 decompressedStream := DecompressGzipToStream(rawStream);
384+ if Assigned(decompressedStream) then
384385 try
385386 bodyStream.CopyFrom(decompressedStream, 0 );
386387 finally
387388 FreeAndNil(decompressedStream);
388- end ;
389+ end
390+ else
391+ bodyStream.CopyFrom(rawStream, 0 ); // Fallback to compressed body
389392 end
390393 else
391394 bodyStream.CopyFrom(rawStream, 0 );
@@ -419,11 +422,14 @@ class function TNetwork.WebRequest(AMethod: TWebMethod; const AUrl: string; cons
419422 if SameText(contentEncoding, ' gzip' ) and IsGzip(rawStream) then
420423 begin
421424 decompressedStream := DecompressGzipToStream(rawStream);
425+ if Assigned(decompressedStream) then
422426 try
423427 bodyStream.CopyFrom(decompressedStream, 0 );
424428 finally
425429 FreeAndNil(decompressedStream);
426- end ;
430+ end
431+ else
432+ bodyStream.CopyFrom(rawStream, 0 ); // Fallback to compressed body
427433 end
428434 else
429435 bodyStream.CopyFrom(rawStream, 0 );
@@ -463,55 +469,54 @@ class function TNetwork.DecompressGzipToStream(Compressed: TMemoryStream): TMemo
463469 dataPos: integer;
464470begin
465471 zstream := Default(TZStream);
472+ Result := TMemoryStream.Create;
473+ try
474+ // Basic validation: gzip header
475+ if Compressed.Size < 10 then
476+ raise Exception.Create(' Compressed data too small for gzip' );
477+ p := Compressed.Memory;
478+ if (p[0 ] <> $1F ) or (p[1 ] <> $8B) then
479+ raise Exception.Create(' Not a gzip stream (invalid ID bytes)' );
480+
481+ // Check compression method (must be deflate, 8)
482+ if p[2 ] <> 8 then
483+ raise Exception.Create(' Unsupported compression method (not deflate)' );
484+
485+ flags := p[3 ];
486+ dataPos := 10 ; // start after fixed header (10 bytes)
487+
488+ // Skip extra field (FEXTRA) if present
489+ if (flags and $04 ) <> 0 then
490+ begin
491+ if Compressed.Size < int64(dataPos) + 2 then
492+ raise Exception.Create(' Truncated gzip: FEXTRA length missing' );
493+ xlen := p[dataPos] or (p[dataPos + 1 ] shl 8 );
494+ Inc(dataPos, 2 + xlen);
495+ end ;
466496
467- // Basic validation: gzip header
468- if Compressed.Size < 10 then
469- raise Exception.Create(' Compressed data too small for gzip' );
470- p := Compressed.Memory;
471- if (p[0 ] <> $1F ) or (p[1 ] <> $8B) then
472- raise Exception.Create(' Not a gzip stream (invalid ID bytes)' );
473-
474- // Check compression method (must be deflate, 8)
475- if p[2 ] <> 8 then
476- raise Exception.Create(' Unsupported compression method (not deflate)' );
477-
478- flags := p[3 ];
479- dataPos := 10 ; // start after fixed header (10 bytes)
480-
481- // Skip extra field (FEXTRA) if present
482- if (flags and $04 ) <> 0 then
483- begin
484- if Compressed.Size < int64(dataPos) + 2 then
485- raise Exception.Create(' Truncated gzip: FEXTRA length missing' );
486- xlen := p[dataPos] or (p[dataPos + 1 ] shl 8 );
487- Inc(dataPos, 2 + xlen);
488- end ;
489-
490- // Skip original filename (FNAME) if present (null-terminated)
491- if (flags and $08 ) <> 0 then
492- begin
493- while (dataPos < Compressed.Size) and (p[dataPos] <> 0 ) do
494- Inc(dataPos);
495- Inc(dataPos); // skip null terminator
496- end ;
497+ // Skip original filename (FNAME) if present (null-terminated)
498+ if (flags and $08 ) <> 0 then
499+ begin
500+ while (dataPos < Compressed.Size) and (p[dataPos] <> 0 ) do
501+ Inc(dataPos);
502+ Inc(dataPos); // skip null terminator
503+ end ;
497504
498- // Skip file comment (FCOMMENT) if present (null-terminated)
499- if (flags and $10 ) <> 0 then
500- begin
501- while (dataPos < Compressed.Size) and (p[dataPos] <> 0 ) do
505+ // Skip file comment (FCOMMENT) if present (null-terminated)
506+ if (flags and $10 ) <> 0 then
507+ begin
508+ while (dataPos < Compressed.Size) and (p[dataPos] <> 0 ) do
509+ Inc(dataPos);
502510 Inc(dataPos);
503- Inc(dataPos);
504- end ;
511+ end ;
505512
506- // Skip header CRC (FHCRC) if present (2 bytes)
507- if (flags and $02 ) <> 0 then
508- Inc(dataPos, 2 );
513+ // Skip header CRC (FHCRC) if present (2 bytes)
514+ if (flags and $02 ) <> 0 then
515+ Inc(dataPos, 2 );
509516
510- if dataPos >= Compressed.Size then
511- raise Exception.Create(' No compressed data after gzip header' );
517+ if dataPos >= Compressed.Size then
518+ raise Exception.Create(' No compressed data after gzip header' );
512519
513- Result := TMemoryStream.Create;
514- try
515520 { $PUSH}
516521 { $NOTES OFF}
517522
@@ -534,23 +539,25 @@ class function TNetwork.DecompressGzipToStream(Compressed: TMemoryStream): TMemo
534539
535540 err := inflate(zstream, Z_NO_FLUSH);
536541 if err < 0 then
537- raise Exception.Create(' inflate error: ' + IntToStr(err));
542+ begin
543+ FreeAndNil(Result);
544+ Exit;
545+ end ;
538546
539547 bytesWritten := SizeOf(outBuffer) - zstream.avail_out;
540548 if bytesWritten > 0 then
541549 Result.Write(outBuffer, bytesWritten);
542550
543551 until err = Z_STREAM_END; // End of stream reached
544-
545552 finally
546553 inflateEnd(zstream);
547554 end ;
548555 { $POP}
549556
550557 Result.Position := 0 ;
551558 except
552- Result.Free ;
553- raise;
559+ FreeAndNil( Result) ;
560+ // No raise;
554561 end ;
555562end ;
556563
0 commit comments