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
89
stb_image.h
89
stb_image.h
@ -5392,11 +5392,49 @@ static int stbi__psd_test(stbi__context *s)
|
|||||||
return r;
|
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)
|
static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||||
{
|
{
|
||||||
int pixelCount;
|
int pixelCount;
|
||||||
int channelCount, compression;
|
int channelCount, compression;
|
||||||
int channel, i, count, len;
|
int channel, i;
|
||||||
int bitdepth;
|
int bitdepth;
|
||||||
int w,h;
|
int w,h;
|
||||||
stbi_uc *out;
|
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);
|
*p = (channel == 3 ? 255 : 0);
|
||||||
} else {
|
} else {
|
||||||
// Read the RLE data.
|
// Read the RLE data.
|
||||||
count = 0;
|
if (!stbi__psd_decode_rle(s, p, pixelCount)) {
|
||||||
while (count < pixelCount) {
|
STBI_FREE(out);
|
||||||
len = stbi__get8(s);
|
return stbi__errpuc("corrupt", "bad RLE data");
|
||||||
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--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6325,20 +6338,29 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
len <<= 8;
|
len <<= 8;
|
||||||
len |= stbi__get8(s);
|
len |= stbi__get8(s);
|
||||||
if (len != width) { STBI_FREE(hdr_data); STBI_FREE(scanline); return stbi__errpf("invalid decoded scanline length", "corrupt HDR"); }
|
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) {
|
for (k = 0; k < 4; ++k) {
|
||||||
|
int nleft;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < width) {
|
while ((nleft = width - i) > 0) {
|
||||||
count = stbi__get8(s);
|
count = stbi__get8(s);
|
||||||
if (count > 128) {
|
if (count > 128) {
|
||||||
// Run
|
// Run
|
||||||
value = stbi__get8(s);
|
value = stbi__get8(s);
|
||||||
count -= 128;
|
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)
|
for (z = 0; z < count; ++z)
|
||||||
scanline[i++ * 4 + k] = value;
|
scanline[i++ * 4 + k] = value;
|
||||||
} else {
|
} else {
|
||||||
// Dump
|
// 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)
|
for (z = 0; z < count; ++z)
|
||||||
scanline[i++ * 4 + k] = stbi__get8(s);
|
scanline[i++ * 4 + k] = stbi__get8(s);
|
||||||
}
|
}
|
||||||
@ -6347,7 +6369,8 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
|
|||||||
for (i=0; i < width; ++i)
|
for (i=0; i < width; ++i)
|
||||||
stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
|
stbi__hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp);
|
||||||
}
|
}
|
||||||
STBI_FREE(scanline);
|
if (scanline)
|
||||||
|
STBI_FREE(scanline);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hdr_data;
|
return hdr_data;
|
||||||
|
Loading…
Reference in New Issue
Block a user