Repository navigation
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. WalkthroughTarga now tracks image and palette buffer capacities. It validates header-derived sizes during allocation, loading, and decoding. Texture-loading paths pass palette buffer sizes to ChangesTGA Buffer Validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Change: Bug fix Suggested reviewers: Merge Risk:
|
[Medium impact] The reviewed changes appear safe to merge.
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Source mode: Auto
- Repository: Unavailable
- Branch: Unavailable
- File: No configuration file from this repository applied
- Commit: Unavailable
- Layers: Organization UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
d870cdb0-4f81-4b53-9e55-cda8fd9d2e70
📒 Files selected for processing: 4
Core/Libraries/Source/WWVegas/WW3D2/textureloader.cppCore/Libraries/Source/WWVegas/WW3D2/texturethumbnail.cppCore/Libraries/Source/WWVegas/WWLib/TARGA.cppCore/Libraries/Source/WWVegas/WWLib/TARGA.h
Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.
| static long TGA_PaletteSize(const TGAHeader& header) | ||
| { | ||
| const long depth = (header.CMapDepth >> 3); | ||
| if ((header.CMapStart < 0) || (header.CMapLength <= 0) || (depth <= 0) || (depth > 4)) { | ||
| return 0; | ||
| } | ||
| return ((long)header.CMapStart + (long)header.CMapLength) * depth; | ||
| } |
There was a problem hiding this comment.
Suggested:
static long TGA_PaletteSize(const TGAHeader& header)
{
if ((header.CMapStart < 0) || (header.CMapLength <= 0) ||
((header.CMapDepth != 16) && (header.CMapDepth != 24) && (header.CMapDepth != 32))) {
return 0;
}
const long depth = (header.CMapDepth >> 3);
return ((long)header.CMapStart + (long)header.CMapLength) * depth;
}Check CMapDepth explicitly for 16, 24, or 32 before shifting. The current check accepts every value from 8 through 39—for example, 31 is treated like 24 bits. This would reject unsupported palette depths.
There was a problem hiding this comment.
I would break the conditions up a bit into at least two if statements to improve readability.
Maybe test the size and depth in different if statements.
Then do the same for image size.
There was a problem hiding this comment.
Done. PixelDepth is limited to 8, 16, 24 and 32 too, the depths Get_WW3D_Format supports.
|
Same fix can also be applied to |
The max2w3d copy is only used to save. The exporter never loads a TGA through it, so no file header reaches that code. |
xezon
left a comment
There was a problem hiding this comment.
THis looks suspicious. Maybe needs AI review passes?
| void YFlip(); | ||
|
|
||
| char* SetImage(char* buffer); | ||
| char* SetImage(char* buffer, long size = 0); |
There was a problem hiding this comment.
Is the zero default deliberate? If yes why?
There was a problem hiding this comment.
Yes. 0 means the buffer capacity is unknown, and Load rejects it. The callers that leave it out only use the buffer to save an image, which doesn't need it.
There was a problem hiding this comment.
The asymmetry to SetPalette, which does not take a 0 defaulted size argument, looks unfavourable. Can we make the interface consistent?
There was a problem hiding this comment.
Done, SetImage takes a required size now like SetPalette. The callers pass their buffer size.
Restructured it so Load only uses the member buffers. Tested 28 TGA files in a MinGW i686 harness. The 15 valid ones decode to the same pixels as main, including flips, RLE and nonzero CMapStart. All 13 malformed ones are rejected with no write outside their buffers. Undersized and unsized caller buffers are rejected too. |
28c90c1 to
81167bf
Compare
xezon
left a comment
There was a problem hiding this comment.
This change is difficult to understand.
| count &= 0x7F; | ||
| count++; | ||
|
|
||
| if ((unsigned long)count > pixel_count) |
There was a problem hiding this comment.
Both packet types store the pixel count minus one in the low 7 bits. Main decoded it separately in each branch, so I moved that above the branches and added one check that rejects a packet with more pixels than are left in the image. Without it a bad count writes past the end of mImage.
There was a problem hiding this comment.
I still do not understand this code. It is unclear what "a run of pixels" means. Can you express the code and/or comments in a way that this becomes clear?
I assume that "run of pixels" refers to pixels of the same color one after another. But the way the code is expressed do not explain this.
There was a problem hiding this comment.
Both packet types store the pixel count minus one in the low 7 bits. Main decoded it separately in each branch, so I moved that above the branches and added one check that rejects a packet with more pixels than are left in the image. Without it a bad count writes past the end of mImage.
|
Simplified it along the inline comments. The size helpers no longer undo each other, the fail branches come last, and there are two TSH comments instead of four. |
|
Update is not pushed. |
|
Pushed now, sorry |
xezon
left a comment
There was a problem hiding this comment.
Most looks ok, but the "run of pixels" are still confusing.
| #include <utility> | ||
|
|
||
| // TheSuperHackers @fix bobtista 22/10/2026 Compute the buffer sizes from the header, or 0 when the header is invalid. | ||
| static long TGA_PaletteBufferSize(const TGAHeader& header) |
There was a problem hiding this comment.
Instead of making these static functions here, how about making them members of struct _TGAHeader?
There was a problem hiding this comment.
Done, the helpers are TGAHeader members now.
| if ((header.Width <= 0) || (header.Height <= 0)) { | ||
| return 0; | ||
| } | ||
| return (long)header.Width * (long)header.Height; |
There was a problem hiding this comment.
or return max(header.Width, 0) * max(header.Height, 0)
| count &= 0x7F; | ||
| count++; | ||
|
|
||
| if ((unsigned long)count > pixel_count) |
There was a problem hiding this comment.
I still do not understand this code. It is unclear what "a run of pixels" means. Can you express the code and/or comments in a way that this becomes clear?
I assume that "run of pixels" refers to pixels of the same color one after another. But the way the code is expressed do not explain this.
|
Rewrote the comments in DecodeImage to describe the packet format sorry that was confusing |
Targa::Loadtrusts the sizes in the file header. The color map is read atCMapStart * depthforCMapLength * depthbytes into the caller's palette buffer, and the texture loaders pass a 1024 byte array.WidthandHeightare signed, and their product with the pixel depth can overflow.DecodeImagekeeps writing when a packet count is larger than the pixels left.Now
SetPaletteandSetImagetake the buffer size, andLoadrejects a color map or image that does not fit its buffer. Invalid dimensions and depths, and sizes that overflow, are rejected.DecodeImagestops at a packet that would pass the end of the image.Todo: