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