libsixel
libsixel copied to clipboard
heap-buffer-overflow /src/tosixel.c:848 in sixel_encode_body_ormode
This applies to the code in PR #133 that was merged into the libsixel/libsixel fork in https://github.com/libsixel/libsixel/pull/5. More details in https://github.com/libsixel/libsixel/issues/72. I'm posting here because that fork is now dead, so this seems like the best place for it to be seen by future maintainers.
The overflow occurs when it's trying parse the last sixel slice of the image, and the height is either an exact multiple of 6 or one scanline more than that. In both cases it tries to read more data than it should.
This code was also missing a buf_p increment when iterating over the width, which meant it was always just reading from the first pixel column.
Both issues should be fixed by the patch below:
diff --git a/src/tosixel.c b/src/tosixel.c
index af54798..3365f8f 100644
--- a/src/tosixel.c
+++ b/src/tosixel.c
@@ -836,7 +836,7 @@ sixel_encode_body_ormode(
buf += (width * 6);
}
- if (cur_h > height) {
+ if (cur_h - height < 6) {
for (plane = 0; plane < nplanes; plane++) {
sixel_putc(output->buffer + output->pos, '#');
sixel_advance(output, 1);
@@ -844,7 +844,7 @@ sixel_encode_body_ormode(
sixel_advance(output, nwrite);
buf_p = buf;
- for (x = 0; x < width; x++) {
+ for (x = 0; x < width; x++, buf_p++) {
int pix = ((buf_p[0] >> plane) & 0x1);
switch(cur_h - height) {
@@ -858,9 +858,10 @@ sixel_encode_body_ormode(
pix |= (((buf_p[width * 2] >> plane) << 2) & 0x4);
/* Fall through */
case 4:
- default:
pix |= (((buf_p[width] >> plane) << 1) & 0x2);
/* Fall through */
+ default:
+ break;
}
sixel_put_pixel(output, pix);
}