| 5529 | |
| 5530 | |
| 5531 | static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) |
| 5532 | { |
| 5533 | stbi_uc *out; |
| 5534 | unsigned int mr=0,mg=0,mb=0,ma=0, all_a; |
| 5535 | stbi_uc pal[256][4]; |
| 5536 | int psize=0,i,j,width; |
| 5537 | int flip_vertically, pad, target; |
| 5538 | stbi__bmp_data info; |
| 5539 | STBI_NOTUSED(ri); |
| 5540 | |
| 5541 | info.all_a = 255; |
| 5542 | if (stbi__bmp_parse_header(s, &info) == NULL) |
| 5543 | return NULL; // error code already set |
| 5544 | |
| 5545 | flip_vertically = ((int) s->img_y) > 0; |
| 5546 | s->img_y = abs((int) s->img_y); |
| 5547 | |
| 5548 | if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); |
| 5549 | if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)"); |
| 5550 | |
| 5551 | mr = info.mr; |
| 5552 | mg = info.mg; |
| 5553 | mb = info.mb; |
| 5554 | ma = info.ma; |
| 5555 | all_a = info.all_a; |
| 5556 | |
| 5557 | if (info.hsz == 12) { |
| 5558 | if (info.bpp < 24) |
| 5559 | psize = (info.offset - info.extra_read - 24) / 3; |
| 5560 | } else { |
| 5561 | if (info.bpp < 16) |
| 5562 | psize = (info.offset - info.extra_read - info.hsz) >> 2; |
| 5563 | } |
| 5564 | if (psize == 0) { |
| 5565 | // accept some number of extra bytes after the header, but if the offset points either to before |
| 5566 | // the header ends or implies a large amount of extra data, reject the file as malformed |
| 5567 | int bytes_read_so_far = s->callback_already_read + (int)(s->img_buffer - s->img_buffer_original); |
| 5568 | int header_limit = 1024; // max we actually read is below 256 bytes currently. |
| 5569 | int extra_data_limit = 256*4; // what ordinarily goes here is a palette; 256 entries*4 bytes is its max size. |
| 5570 | if (bytes_read_so_far <= 0 || bytes_read_so_far > header_limit) { |
| 5571 | return stbi__errpuc("bad header", "Corrupt BMP"); |
| 5572 | } |
| 5573 | // we established that bytes_read_so_far is positive and sensible. |
| 5574 | // the first half of this test rejects offsets that are either too small positives, or |
| 5575 | // negative, and guarantees that info.offset >= bytes_read_so_far > 0. this in turn |
| 5576 | // ensures the number computed in the second half of the test can't overflow. |
| 5577 | if (info.offset < bytes_read_so_far || info.offset - bytes_read_so_far > extra_data_limit) { |
| 5578 | return stbi__errpuc("bad offset", "Corrupt BMP"); |
| 5579 | } else { |
| 5580 | stbi__skip(s, info.offset - bytes_read_so_far); |
| 5581 | } |
| 5582 | } |
| 5583 | |
| 5584 | if (info.bpp == 24 && ma == 0xff000000) |
| 5585 | s->img_n = 3; |
| 5586 | else |
| 5587 | s->img_n = ma ? 4 : 3; |
| 5588 | if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 |
no test coverage detected