ref: f67c1281ff7152c2705a12bcedb4add1c517fbdc
parent: 73f023074f6ae776e2dafcff71ff0b78e8af5231
author: Lennart Augustsson <lennart@augustsson.net>
date: Wed Oct 2 05:22:36 EDT 2024
Fix a buffer overflow bug
--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -2611,19 +2611,19 @@
evalstring(NODEPTR n)
{
size_t sz = 100;
- char *name = MALLOC(sz);
+ char *buf = MALLOC(sz);
size_t offs;
uvalue_t c;
NODEPTR x;
struct bytestring bs;
- if (!name)
+ if (!buf)
memerr();
for (offs = 0;;) {
if (offs >= sz - 4) {
sz *= 2;
- name = REALLOC(name, sz);
- if (!name)
+ buf = REALLOC(buf, sz);
+ if (!buf)
memerr();
}
n = evali(n);
@@ -2631,23 +2631,23 @@
break;
else if (GETTAG(n) == T_AP && GETTAG(x = indir(&FUN(n))) == T_AP && GETTAG(indir(&FUN(x))) == T_O) { /* Cons */
PUSH(n); /* protect from GC */
- c = (uvalue_t)evalint(ARG(x));
+ c = evalint(ARG(x));
n = POPTOP();
/* XXX Encode as UTF8 */
if (c < 0x80) {
- name[offs++] = (char)c;
+ buf[offs++] = (char)c;
} else if (c < 0x800) {
- name[offs++] = ((c >> 6 ) ) | 0xc0;
- name[offs++] = ((c ) & 0x3f) | 0x80;
+ buf[offs++] = ((c >> 6 ) ) | 0xc0;
+ buf[offs++] = ((c ) & 0x3f) | 0x80;
} else if (c < 0x10000) {
- name[offs++] = ((c >> 12) ) | 0xe0;
- name[offs++] = ((c >> 6 ) & 0x3f) | 0x80;
- name[offs++] = ((c ) & 0x3f) | 0x80;
+ buf[offs++] = ((c >> 12) ) | 0xe0;
+ buf[offs++] = ((c >> 6 ) & 0x3f) | 0x80;
+ buf[offs++] = ((c ) & 0x3f) | 0x80;
} else if (c < 0x110000) {
- name[offs++] = ((c >> 18) ) | 0xf0;
- name[offs++] = ((c >> 12) & 0x3f) | 0x80;
- name[offs++] = ((c >> 6 ) & 0x3f) | 0x80;
- name[offs++] = ((c ) & 0x3f) | 0x80;
+ buf[offs++] = ((c >> 18) ) | 0xf0;
+ buf[offs++] = ((c >> 12) & 0x3f) | 0x80;
+ buf[offs++] = ((c >> 6 ) & 0x3f) | 0x80;
+ buf[offs++] = ((c ) & 0x3f) | 0x80;
} else {
ERR("invalid char");
}
@@ -2656,9 +2656,9 @@
ERR("evalstring not Nil/Cons");
}
}
- name[offs] = 0;
+ buf[offs] = 0; /* in case we use it as a C string */
bs.size = offs;
- bs.string = name;
+ bs.string = buf;
return bs;
}
@@ -2676,7 +2676,7 @@
if (!buf)
memerr();
for (offs = 0;;) {
- if (offs >= sz) {
+ if (offs >= sz - 1) {
sz *= 2;
buf = REALLOC(buf, sz);
if (!buf)
@@ -2687,14 +2687,15 @@
break;
else if (GETTAG(n) == T_AP && GETTAG(x = indir(&FUN(n))) == T_AP && GETTAG(indir(&FUN(x))) == T_O) { /* Cons */
PUSH(n); /* protect from GC */
- c = (uvalue_t)evalint(ARG(x));
+ c = evalint(ARG(x));
n = POPTOP();
- buf[offs++] = (char)c;
+ buf[offs++] = c;
n = ARG(n);
} else {
ERR("evalbytestring not Nil/Cons");
}
}
+ buf[offs] = 0; /* in case we use it as a C string */
bs.size = offs;
bs.string = buf;
return bs;