Reject invalid and out of range numbers.

This commit is contained in:
Nicholas Marriott
2026-10-12 13:49:23 +01:00
parent cafeed9d22
commit fcb9ac2b2b

View File

@@ -18,6 +18,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -133,6 +134,21 @@ sixel_parse_write(struct sixel_image *si, u_int ch)
return (0); return (0);
} }
static int
sixel_parse_number(const char *cp, char **endptr, u_int *value)
{
unsigned long long number;
if (*cp < '0' || *cp > '9')
return (1);
errno = 0;
number = strtoull(cp, endptr, 10);
if (errno == ERANGE || number > UINT_MAX)
return (1);
*value = number;
return (0);
}
static const char * static const char *
sixel_parse_attributes(struct sixel_image *si, const char *cp, const char *end) sixel_parse_attributes(struct sixel_image *si, const char *cp, const char *end)
{ {
@@ -157,7 +173,10 @@ sixel_parse_attributes(struct sixel_image *si, const char *cp, const char *end)
return (NULL); return (NULL);
} }
x = strtoul(endptr + 1, &endptr, 10); if (sixel_parse_number(endptr + 1, &endptr, &x) != 0) {
log_debug("%s: invalid number", __func__);
return (NULL);
}
if (endptr == last || *endptr != ';') { if (endptr == last || *endptr != ';') {
log_debug("%s: missing ;", __func__); log_debug("%s: missing ;", __func__);
return (NULL); return (NULL);
@@ -166,7 +185,10 @@ sixel_parse_attributes(struct sixel_image *si, const char *cp, const char *end)
log_debug("%s: image is too wide", __func__); log_debug("%s: image is too wide", __func__);
return (NULL); return (NULL);
} }
y = strtoul(endptr + 1, &endptr, 10); if (sixel_parse_number(endptr + 1, &endptr, &y) != 0) {
log_debug("%s: invalid number", __func__);
return (NULL);
}
if (endptr != last) { if (endptr != last) {
log_debug("%s: extra ;", __func__); log_debug("%s: extra ;", __func__);
return (NULL); return (NULL);
@@ -200,7 +222,10 @@ sixel_parse_colour(struct sixel_image *si, const char *cp, const char *end)
last++; last++;
} }
c = strtoul(cp, &endptr, 10); if (sixel_parse_number(cp, &endptr, &c) != 0) {
log_debug("%s: invalid number", __func__);
return (NULL);
}
if (c > SIXEL_COLOUR_REGISTERS) { if (c > SIXEL_COLOUR_REGISTERS) {
log_debug("%s: too many colours", __func__); log_debug("%s: too many colours", __func__);
return (NULL); return (NULL);
@@ -211,22 +236,34 @@ sixel_parse_colour(struct sixel_image *si, const char *cp, const char *end)
if (endptr == last || *endptr != ';') if (endptr == last || *endptr != ';')
return (last); return (last);
type = strtoul(endptr + 1, &endptr, 10); if (sixel_parse_number(endptr + 1, &endptr, &type) != 0) {
log_debug("%s: invalid number", __func__);
return (NULL);
}
if (endptr == last || *endptr != ';') { if (endptr == last || *endptr != ';') {
log_debug("%s: missing ;", __func__); log_debug("%s: missing ;", __func__);
return (NULL); return (NULL);
} }
c1 = strtoul(endptr + 1, &endptr, 10); if (sixel_parse_number(endptr + 1, &endptr, &c1) != 0) {
log_debug("%s: invalid number", __func__);
return (NULL);
}
if (endptr == last || *endptr != ';') { if (endptr == last || *endptr != ';') {
log_debug("%s: missing ;", __func__); log_debug("%s: missing ;", __func__);
return (NULL); return (NULL);
} }
c2 = strtoul(endptr + 1, &endptr, 10); if (sixel_parse_number(endptr + 1, &endptr, &c2) != 0) {
log_debug("%s: invalid number", __func__);
return (NULL);
}
if (endptr == last || *endptr != ';') { if (endptr == last || *endptr != ';') {
log_debug("%s: missing ;", __func__); log_debug("%s: missing ;", __func__);
return (NULL); return (NULL);
} }
c3 = strtoul(endptr + 1, &endptr, 10); if (sixel_parse_number(endptr + 1, &endptr, &c3) != 0) {
log_debug("%s: invalid number", __func__);
return (NULL);
}
if (endptr != last) { if (endptr != last) {
log_debug("%s: missing ;", __func__); log_debug("%s: missing ;", __func__);
return (NULL); return (NULL);