Copilot commented on code in PR #3854:
URL: https://github.com/apache/avro/pull/3854#discussion_r3567394100


##########
lang/c++/impl/DataFile.cc:
##########
@@ -627,12 +679,25 @@ void DataFileReaderBase::readDataBlock() {
 
             const uint8_t *data;
             size_t len;
+            const size_t maxLength = maxDecompressLength();
             while (ret != Z_STREAM_END && st->next(&data, &len)) {
                 zs.avail_in = static_cast<uInt>(len);
                 zs.next_in = const_cast<Bytef *>(data);
                 do {
                     if (zs.total_out == uncompressed.size()) {
-                        uncompressed.resize(uncompressed.size() + 
zlibBufGrowSize);
+                        // Reject a block that decompresses to more than the
+                        // allowed maximum, before growing the buffer further.
+                        if (uncompressed.size() >= maxLength) {
+                            (void) inflateEnd(&zs);
+                            throw Exception(
+                                "Decompressed block size exceeds the maximum 
allowed of {} bytes",
+                                maxLength);

Review Comment:
   The deflate over-limit exception currently reports only the limit and uses 
wording that implies the block already exceeded it, but the check triggers when 
the buffer is exactly at the limit and would need to grow further. Consider 
including an explicit would-be size (at least `maxLength + 1`, clamped) to make 
the message accurate and consistent with the Snappy/Zstd limit errors that 
report both sizes.



##########
lang/c++/impl/DataFile.cc:
##########
@@ -627,12 +679,25 @@ void DataFileReaderBase::readDataBlock() {
 
             const uint8_t *data;
             size_t len;
+            const size_t maxLength = maxDecompressLength();
             while (ret != Z_STREAM_END && st->next(&data, &len)) {
                 zs.avail_in = static_cast<uInt>(len);
                 zs.next_in = const_cast<Bytef *>(data);
                 do {
                     if (zs.total_out == uncompressed.size()) {
-                        uncompressed.resize(uncompressed.size() + 
zlibBufGrowSize);
+                        // Reject a block that decompresses to more than the
+                        // allowed maximum, before growing the buffer further.
+                        if (uncompressed.size() >= maxLength) {
+                            (void) inflateEnd(&zs);
+                            throw Exception(
+                                "Decompressed block size exceeds the maximum 
allowed of {} bytes",
+                                maxLength);
+                        }
+                        size_t newSize = uncompressed.size() + zlibBufGrowSize;
+                        if (newSize > maxLength) {
+                            newSize = maxLength;
+                        }
+                        uncompressed.resize(newSize);

Review Comment:
   Potential size_t overflow when growing the deflate decompression buffer: 
`uncompressed.size() + zlibBufGrowSize` can wrap if `maxLength` is configured 
near `SIZE_MAX`, causing `newSize` to become small and leading to incorrect 
resizing behavior. Grow using a remaining-capacity calculation to avoid 
overflow before clamping to `maxLength`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to