Skip to content

Commit

Permalink
Merge PR #106, includes security fixes for:
Browse files Browse the repository at this point in the history
  • Loading branch information
saitoha committed Dec 14, 2019
2 parents 2eced29 + 9566e0e commit 93812d6
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 7 deletions.
1 change: 1 addition & 0 deletions include/sixel.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ typedef int SIXELSTATUS;
#define SIXEL_BAD_ALLOCATION (SIXEL_RUNTIME_ERROR | 0x0001) /* malloc() failed */
#define SIXEL_BAD_ARGUMENT (SIXEL_RUNTIME_ERROR | 0x0002) /* bad argument detected */
#define SIXEL_BAD_INPUT (SIXEL_RUNTIME_ERROR | 0x0003) /* bad input detected */
#define SIXEL_BAD_INTEGER_OVERFLOW (SIXEL_RUNTIME_ERROR | 0x0004) /* integer overflow */

#define SIXEL_NOT_IMPLEMENTED (SIXEL_FEATURE_ERROR | 0x0001) /* feature not implemented */

Expand Down
4 changes: 2 additions & 2 deletions src/frompnm.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ load_pnm(unsigned char /* in */ *p,
height = 0;
for (; *s >= '0' && *s <= '9'; ++s) {
height = height * 10 + (*s - '0');
if (width > PNM_MAX_WIDTH) {
if (height > PNM_MAX_HEIGHT) {
status = SIXEL_RUNTIME_ERROR;
sprintf(
message,
Expand All @@ -193,7 +193,7 @@ load_pnm(unsigned char /* in */ *p,
for (; *s >= '0' && *s <= '9'; ++s) {
deps = deps * 10 + (*s - '0');
}
if (width > PNM_MAX_WIDTH) {
if (deps > PNM_MAX_DEPTH) {
status = SIXEL_RUNTIME_ERROR;
sprintf(
message,
Expand Down
31 changes: 27 additions & 4 deletions src/fromsixel.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <stdio.h>
#include <ctype.h> /* isdigit */
#include <string.h> /* memcpy */
#include <limits.h>

#if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
Expand Down Expand Up @@ -367,6 +368,16 @@ parser_context_init(parser_context_t *context)
return status;
}

SIXELSTATUS safe_addition_for_params(parser_context_t *context, unsigned char *p){
int x;

x = *p - '0'; /* 0 <= x <= 9 */
if ((context->param > INT_MAX / 10) || (x > INT_MAX - context->param * 10)) {
return SIXEL_BAD_INTEGER_OVERFLOW;
}
context->param = context->param * 10 + x;
return SIXEL_OK;
}

/* convert sixel data into indexed pixel bytes and palette data */
SIXELAPI SIXELSTATUS
Expand Down Expand Up @@ -446,7 +457,10 @@ sixel_decode_raw_impl(
if (context->param < 0) {
context->param = 0;
}
context->param = context->param * 10 + *p - '0';
status = safe_addition_for_params(context, p);
if (SIXEL_FAILED(status)) {
goto end;
}
p++;
break;
case ';':
Expand Down Expand Up @@ -651,7 +665,10 @@ sixel_decode_raw_impl(
case '7':
case '8':
case '9':
context->param = context->param * 10 + *p - '0';
status = safe_addition_for_params(context, p);
if (SIXEL_FAILED(status)) {
goto end;
}
p++;
break;
case ';':
Expand Down Expand Up @@ -725,7 +742,10 @@ sixel_decode_raw_impl(
case '7':
case '8':
case '9':
context->param = context->param * 10 + *p - '0';
status = safe_addition_for_params(context, p);
if (SIXEL_FAILED(status)) {
goto end;
}
p++;
break;
default:
Expand Down Expand Up @@ -761,7 +781,10 @@ sixel_decode_raw_impl(
case '7':
case '8':
case '9':
context->param = context->param * 10 + *p - '0';
status = safe_addition_for_params(context, p);
if (SIXEL_FAILED(status)) {
goto end;
}
p++;
break;
case ';':
Expand Down
4 changes: 4 additions & 0 deletions src/status.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#define SIXEL_MESSAGE_BAD_ALLOCATION ("runtime error: bad allocation error")
#define SIXEL_MESSAGE_BAD_ARGUMENT ("runtime error: bad argument detected")
#define SIXEL_MESSAGE_BAD_INPUT ("runtime error: bad input detected")
#define SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW ("runtime error: integer overflow")
#define SIXEL_MESSAGE_RUNTIME_ERROR ("runtime error")
#define SIXEL_MESSAGE_LOGIC_ERROR ("logic error")
#define SIXEL_MESSAGE_NOT_IMPLEMENTED ("feature error: not implemented")
Expand Down Expand Up @@ -120,6 +121,9 @@ sixel_helper_format_error(
case SIXEL_BAD_INPUT:
error_string = SIXEL_MESSAGE_BAD_INPUT;
break;
case SIXEL_BAD_INTEGER_OVERFLOW:
error_string = SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW;
break;
default:
error_string = SIXEL_MESSAGE_RUNTIME_ERROR;
break;
Expand Down
26 changes: 25 additions & 1 deletion src/tosixel.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#if defined(HAVE_INTTYPES_H)
# include <inttypes.h>
Expand Down Expand Up @@ -502,6 +503,7 @@ sixel_encode_body(
int mx;
int len;
int pix;
int check_integer_overflow;
unsigned char *map = NULL;
sixel_node_t *np, *tp, top;
int fillable;
Expand Down Expand Up @@ -557,8 +559,30 @@ sixel_encode_body(
fillable = 1;
}
for (x = 0; x < width; x++) {
pix = pixels[y * width + x]; /* color index */
if (y > INT_MAX / width) {
/* integer overflow */
status = SIXEL_BAD_INTEGER_OVERFLOW;
goto end;
}
check_integer_overflow = y * width;
if (check_integer_overflow > INT_MAX - x) {
/* integer overflow */
status = SIXEL_BAD_INTEGER_OVERFLOW;
goto end;
}
pix = pixels[check_integer_overflow + x]; /* color index */
if (pix >= 0 && pix < ncolors && pix != keycolor) {
if (pix > INT_MAX / width) {
/* integer overflow */
status = SIXEL_BAD_INTEGER_OVERFLOW;
goto end;
}
check_integer_overflow = pix * width;
if (check_integer_overflow > INT_MAX - x) {
/* integer overflow */
status = SIXEL_BAD_INTEGER_OVERFLOW;
goto end;
}
map[pix * width + x] |= (1 << i);
}
else if (!palstate) {
Expand Down

0 comments on commit 93812d6

Please sign in to comment.