stb_image: Fix HDR/PSD RLE decoders.
Runs need to be bounds checked. Fixes issues #315, #317.
This commit is contained in:
parent
02190634c2
commit
62f372754f
85
stb_image.h
85
stb_image.h
@ -5392,11 +5392,49 @@ static int stbi__psd_test(stbi__context *s)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount)
|
||||
{
|
||||
int count, nleft, len;
|
||||
|
||||
count = 0;
|
||||
while ((nleft = pixelCount - count) > 0) {
|
||||
len = stbi__get8(s);
|
||||
if (len == 128) {
|
||||
// No-op.
|
||||
} else if (len < 128) {
|
||||
// Copy next len+1 bytes literally.
|
||||
len++;
|
||||
if (len > nleft) return 0; // corrupt data
|
||||
count += len;
|
||||
while (len) {
|
||||
*p = stbi__get8(s);
|
||||
p += 4;
|
||||
len--;
|
||||
}
|
||||
} else if (len > 128) {
|
||||
stbi_uc val;
|
||||
// Next -len+1 bytes in the dest are replicated from next source byte.
|
||||
// (Interpret len as a negative 8-bit int.)
|
||||
len = 257 - len;
|
||||
if (len > nleft) return 0; // corrupt data
|
||||
val = stbi__get8(s);
|
||||
count += len;
|
||||
while (len) {
|
||||
*p = val;
|
||||
p += 4;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
int pixelCount;
|
||||
int channelCount, compression;
|
||||
int channel, i, count, len;
|
||||
int channel, i;
|
||||
int bitdepth;
|
||||
int w,h;
|
||||
stbi_uc *out;
|
||||
@ -5493,34 +5531,9 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
*p = (channel == 3 ? 255 : 0);
|
||||
} else {
|
||||
// Read the RLE data.
|
||||
count = 0;
|
||||
while (count < pixelCount) {
|
||||
len = stbi__get8(s);
|
||||
if (len == 128) {
|
||||
// No-op.
|
||||
} else if (len < 128) {
|
||||
// Copy next len+1 bytes literally.
|
||||
len++;
|
||||
count += len;
|
||||
while (len) {
|
||||
*p = stbi__get8(s);
|
||||
p += 4;
|
||||
len--;
|
||||
}
|
||||
} else if (len > 128) {
|
||||
stbi_uc val;
|
||||
// Next -len+1 bytes in the dest are replicated from next source byte.
|
||||
// (Interpret len as a negative 8-bit int.)
|
||||
len ^= 0x0FF;
|
||||
len += 2;
|
||||
val = stbi__get8(s);
|
||||
count += len;
|
||||
while (len) {
|
||||
*p = val;
|
||||
p += 4;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
if (!stbi__psd_decode_rle(s, p, pixelCount)) {
|
||||
STBI_FREE(out);
|
||||
return stbi__errpuc("corrupt", "bad RLE data");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6325,20 +6338,29 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
||||
len <<= 8;
|
||||
len |= stbi__get8(s);
|
||||
if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
|
||||
if (scanline == NULL) scanline = (stbi_uc *) stbi__malloc(width * 4);
|
||||
if (scanline == NULL) {
|
||||
scanline = (stbi_uc *) stbi__malloc_mad2(width, 4, 0);
|
||||
if (!scanline) {
|
||||
STBI_FREE(hdr_data);
|
||||
return stbi__errpf("outofmem", "Out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; k < 4; ++k) {
|
||||
int nleft;
|
||||
i = 0;
|
||||
while (i < width) {
|
||||
while ((nleft = width - i) > 0) {
|
||||
count = stbi__get8(s);
|
||||
if (count > 128) {
|
||||
// Run
|
||||
value = stbi__get8(s);
|
||||
count -= 128;
|
||||
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
|
||||
for (z = 0; z < count; ++z)
|
||||
scanline[i++ * 4 + k] = value;
|
||||
} else {
|
||||
// Dump
|
||||
if (count > nleft) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("corrupt", "bad RLE data in HDR"); }
|
||||
for (z = 0; z < count; ++z)
|
||||
scanline[i++ * 4 + k] = stbi__get8(s);
|
||||
}
|
||||
@ -6347,6 +6369,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
||||
for (i=0; i < width; ++i)
|
||||
stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
|
||||
}
|
||||
if (scanline)
|
||||
STBI_FREE(scanline);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user