Skip to content

Commit b8e0a91

Browse files
committed
ATRONIX: Fix bias overflow in Remove_Series
bias is 16-bit, and len is 32-bit, so check overflow before modifing bias. This fixes the crash: a: copy "" insert/dup a #"a" to integer! #10ffff take/part a 3 take/part a to integer! #f0010 insert/dup a #"b" 10 a: 1 ;force a to recycle recycle print a (cherry picked from commit cc625be)
1 parent f3f06b3 commit b8e0a91

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

src/core/m-series.c

+22-7
Original file line numberDiff line numberDiff line change
@@ -351,13 +351,28 @@
351351
CLEAR(series->data, SERIES_WIDE(series)); // terminate
352352
} else {
353353
// Add bias to head:
354-
SERIES_ADD_BIAS(series, len);
355-
SERIES_REST(series) -= len;
356-
series->data += SERIES_WIDE(series) * len;
357-
if (NZ(start = SERIES_BIAS(series))) {
358-
// If more than half biased:
359-
if (start >= MAX_SERIES_BIAS || start > SERIES_REST(series))
360-
Reset_Bias(series);
354+
REBCNT bias = SERIES_BIAS(series);
355+
if (REB_U32_ADD_OF(bias, len, &bias)) {
356+
Trap0(RE_OVERFLOW);
357+
}
358+
if (bias > 0xffff) { //bias is 16-bit, so a simple SERIES_ADD_BIAS could overflow it
359+
REBYTE *data = series->data;
360+
361+
data += SERIES_WIDE(series) * len;
362+
series->data -= SERIES_WIDE(series) * SERIES_BIAS(series);
363+
SERIES_REST(series) += bias;
364+
SERIES_SET_BIAS(series, 0);
365+
366+
memmove(series->data, data, SERIES_USED(series));
367+
} else {
368+
SERIES_SET_BIAS(series, bias);
369+
SERIES_REST(series) -= len;
370+
series->data += SERIES_WIDE(series) * len;
371+
if (NZ(start = SERIES_BIAS(series))) {
372+
// If more than half biased:
373+
if (start >= MAX_SERIES_BIAS || start > SERIES_REST(series))
374+
Reset_Bias(series);
375+
}
361376
}
362377
}
363378
return;

0 commit comments

Comments
 (0)