mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-16 19:15:14 -04:00
Fix out of bounds read in PNG decoder, don't crash on invalid scanline filter byte (Thanks khang06, addresses #590)
This commit is contained in:
parent
8999a1accb
commit
831330df5c
@ -113,10 +113,6 @@ static void Png_Reconstruct(uint8_t type, uint8_t bytesPerPixel, uint8_t* line,
|
||||
else { line[i] += c; }
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
Logger_Abort("PNG scanline has invalid filter type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -475,11 +471,13 @@ ReturnCode Png_Decode(Bitmap* bmp, struct Stream* stream) {
|
||||
/* reached end of buffer, cycle back to start */
|
||||
if (bufferIdx == bufferLen) bufferIdx = 0;
|
||||
|
||||
for (rowY = begY; rowY < endY; rowY++, curY++) {
|
||||
/* NOTE: Need to check curY too, in case IDAT is corrupted and has extra data */
|
||||
for (rowY = begY; rowY < endY && curY < bmp->Height; rowY++, curY++) {
|
||||
uint32_t priorY = rowY == 0 ? bufferRows : rowY;
|
||||
uint8_t* prior = &buffer[(priorY - 1) * scanlineBytes];
|
||||
uint8_t* scanline = &buffer[rowY * scanlineBytes];
|
||||
|
||||
if (scanline[0] > PNG_FILTER_PAETH) return PNG_ERR_INVALID_SCANLINE;
|
||||
Png_Reconstruct(scanline[0], bytesPerPixel, &scanline[1], &prior[1], scanlineSize);
|
||||
rowExpander(bmp->Width, palette, &scanline[1], Bitmap_GetRow(bmp, curY));
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ enum ERRORS_ALL {
|
||||
PNG_ERR_INVALID_SIG, PNG_ERR_INVALID_HDR_SIZE, PNG_ERR_TOO_WIDE, PNG_ERR_TOO_TALL,
|
||||
PNG_ERR_INVALID_COL_BPP, PNG_ERR_COMP_METHOD, PNG_ERR_FILTER, PNG_ERR_INTERLACED,
|
||||
PNG_ERR_PAL_SIZE, PNG_ERR_TRANS_COUNT, PNG_ERR_TRANS_INVALID, PNG_ERR_INVALID_END_SIZE, PNG_ERR_NO_DATA,
|
||||
PNG_ERR_INVALID_SCANLINE,
|
||||
/* ZIP archive decoding errors */
|
||||
ZIP_ERR_TOO_MANY_ENTRIES, ZIP_ERR_SEEK_END_OF_CENTRAL_DIR, ZIP_ERR_NO_END_OF_CENTRAL_DIR,
|
||||
ZIP_ERR_SEEK_CENTRAL_DIR, ZIP_ERR_INVALID_CENTRAL_DIR,
|
||||
|
@ -117,6 +117,7 @@ static const char* Logger_GetCCErrorDesc(ReturnCode res) {
|
||||
case PNG_ERR_TRANS_INVALID: return "Transparency invalid for color type";
|
||||
case PNG_ERR_INVALID_END_SIZE: return "Non-empty IEND chunk";
|
||||
case PNG_ERR_NO_DATA: return "No image in PNG";
|
||||
case PNG_ERR_INVALID_SCANLINE: return "Invalid PNG scanline type";
|
||||
|
||||
/* ZIP archive decoding errors */ /*
|
||||
ZIP_ERR_TOO_MANY_ENTRIES,
|
||||
|
18
src/Window.c
18
src/Window.c
@ -2803,7 +2803,7 @@ static EM_BOOL Window_KeyPress(int type, const EmscriptenKeyboardEvent* ev, void
|
||||
}
|
||||
|
||||
static void Window_HookEvents(void) {
|
||||
emscripten_set_wheel_callback("#canvas", NULL, 0, Window_MouseWheel);
|
||||
emscripten_set_wheel_callback("#window", NULL, 0, Window_MouseWheel);
|
||||
emscripten_set_mousedown_callback("#canvas", NULL, 0, Window_MouseButton);
|
||||
emscripten_set_mouseup_callback("#canvas", NULL, 0, Window_MouseButton);
|
||||
emscripten_set_mousemove_callback("#canvas", NULL, 0, Window_MouseMove);
|
||||
@ -2819,10 +2819,10 @@ static void Window_HookEvents(void) {
|
||||
emscripten_set_keyup_callback("#window", NULL, 0, Window_Key);
|
||||
emscripten_set_keypress_callback("#window", NULL, 0, Window_KeyPress);
|
||||
|
||||
emscripten_set_touchstart_callback(0, NULL, 0, Window_TouchStart);
|
||||
emscripten_set_touchmove_callback(0, NULL, 0, Window_TouchMove);
|
||||
emscripten_set_touchend_callback(0, NULL, 0, Window_TouchEnd);
|
||||
emscripten_set_touchcancel_callback(0, NULL, 0, Window_TouchEnd);
|
||||
emscripten_set_touchstart_callback("#window", NULL, 0, Window_TouchStart);
|
||||
emscripten_set_touchmove_callback("#window", NULL, 0, Window_TouchMove);
|
||||
emscripten_set_touchend_callback("#window", NULL, 0, Window_TouchEnd);
|
||||
emscripten_set_touchcancel_callback("#window", NULL, 0, Window_TouchEnd);
|
||||
}
|
||||
|
||||
static void Window_UnhookEvents(void) {
|
||||
@ -2842,10 +2842,10 @@ static void Window_UnhookEvents(void) {
|
||||
emscripten_set_keyup_callback("#window", NULL, 0, NULL);
|
||||
emscripten_set_keypress_callback("#window", NULL, 0, NULL);
|
||||
|
||||
emscripten_set_touchstart_callback(0, NULL, 0, NULL);
|
||||
emscripten_set_touchmove_callback(0, NULL, 0, NULL);
|
||||
emscripten_set_touchend_callback(0, NULL, 0, NULL);
|
||||
emscripten_set_touchcancel_callback(0, NULL, 0, NULL);
|
||||
emscripten_set_touchstart_callback("#window", NULL, 0, NULL);
|
||||
emscripten_set_touchmove_callback("#window", NULL, 0, NULL);
|
||||
emscripten_set_touchend_callback("#window", NULL, 0, NULL);
|
||||
emscripten_set_touchcancel_callback("#window", NULL, 0, NULL);
|
||||
}
|
||||
|
||||
void Window_Init(void) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user