Skip to content

Commit 8dbe828

Browse files
committed
Add casts to u32 before left shifts to address ubsan edge cases.
Common idiom that wasn't always applied, especially in emit.c and cfuns.c
1 parent 88c42ff commit 8dbe828

7 files changed

Lines changed: 45 additions & 34 deletions

File tree

src/core/cfuns.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ static JanetSlot do_get(JanetFopts opts, JanetSlot *args) {
188188
janetc_copy(c, t, dflt_slot);
189189
if (target_is_default) janetc_freeslot(c, dflt_slot);
190190
int32_t current = janet_v_count(c->buffer);
191-
c->buffer[label] |= (current - label) << 16;
191+
c->buffer[label] |= (uint32_t)(current - label) << 16;
192192
return t;
193193
} else {
194194
return opreduce(opts, args, JOP_GET, 0, janet_wrap_nil(), janet_wrap_nil());
@@ -345,7 +345,7 @@ static JanetSlot compreduce(
345345
int32_t end = janet_v_count(c->buffer);
346346
for (i = 0; i < janet_v_count(labels); i++) {
347347
int32_t label = labels[i];
348-
c->buffer[label] |= ((end - label) << 16);
348+
c->buffer[label] |= ((uint32_t)(end - label) << 16);
349349
}
350350
janet_v_free(labels);
351351
return t;

src/core/compile.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,11 @@ Shadowing janetc_shadowcheck(JanetCompiler *c, const uint8_t *sym) {
280280
for (int32_t i = len - 1; i >= 0; i--) {
281281
SymPair *pair = scope->syms + i;
282282
if (pair->sym == sym) {
283-
janet_assert(!is_global, "shadowing analysis is incorrect. compiler bug");
283+
if (is_global) {
284+
/* This can happen in a top level form like (def [x [x y]] [1 [2 3]])` where a symbol is reused in one expression */
285+
/* janet_assert(!is_global, "shadowing analysis is incorrect. compiler bug"); */
286+
return JANETC_SHADOW_GLOBAL_HIDES_GLOBAL;
287+
}
284288
return JANETC_SHADOW_LOCAL_HIDES_LOCAL;
285289
}
286290
}

src/core/corelib.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -441,19 +441,22 @@ JANET_CORE_FN(janet_core_range,
441441
start = janet_getnumber(argv, 0);
442442
stop = janet_getnumber(argv, 1);
443443
step = janet_getnumber(argv, 2);
444-
count = (step > 0) ? (stop - start) / step :
445-
((step < 0) ? (stop - start) / step : 0);
444+
count = (step > 0.0) ? (stop - start) / step :
445+
((step < 0.0) ? (stop - start) / step : 0.0);
446446
} else if (argc == 2) {
447-
start = janet_getnumber(argv, 0);
448-
stop = janet_getnumber(argv, 1);
447+
start = janet_getnumber(argv, 0.0);
448+
stop = janet_getnumber(argv, 1.0);
449449
count = stop - start;
450450
} else {
451-
stop = janet_getnumber(argv, 0);
451+
stop = janet_getnumber(argv, 0.0);
452452
count = stop;
453453
}
454-
count = (count > 0) ? count : 0;
454+
if (isinf(step)) {
455+
janet_panic("infinite step not allowed");
456+
}
457+
count = (count > 0.0) ? count : 0.0;
455458
int32_t int_count;
456-
janet_assert(count >= 0, "bad range code");
459+
janet_assert(count >= 0.0, "bad range code");
457460
if (count > (double) INT32_MAX) {
458461
janet_panicf("range is too large, %f elements", count);
459462
} else {

src/core/emit.c

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ static int32_t janetc_const(JanetCompiler *c, Janet x) {
7878
static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
7979
switch (janet_type(k)) {
8080
case JANET_NIL:
81-
janetc_emit(c, (reg << 8) | JOP_LOAD_NIL);
81+
janetc_emit(c, ((uint32_t) reg << 8) | JOP_LOAD_NIL);
8282
break;
8383
case JANET_BOOLEAN:
84-
janetc_emit(c, (reg << 8) |
84+
janetc_emit(c, ((uint32_t) reg << 8) |
8585
(janet_unwrap_boolean(k) ? JOP_LOAD_TRUE : JOP_LOAD_FALSE));
8686
break;
8787
case JANET_NUMBER: {
@@ -93,17 +93,17 @@ static void janetc_loadconst(JanetCompiler *c, Janet k, int32_t reg) {
9393
goto do_constant;
9494
uint32_t iu = (uint32_t)i;
9595
janetc_emit(c,
96-
(iu << 16) |
97-
(reg << 8) |
96+
((uint32_t) iu << 16) |
97+
((uint32_t) reg << 8) |
9898
JOP_LOAD_INTEGER);
9999
break;
100100
}
101101
default:
102102
do_constant: {
103103
int32_t cindex = janetc_const(c, k);
104104
janetc_emit(c,
105-
(cindex << 16) |
106-
(reg << 8) |
105+
((uint32_t) cindex << 16) |
106+
((uint32_t) reg << 8) |
107107
JOP_LOAD_CONSTANT);
108108
break;
109109
}
@@ -120,8 +120,8 @@ static void janetc_movenear(JanetCompiler *c,
120120
/* If we also are a reference, deref the one element array */
121121
if (src.flags & JANET_SLOT_REF) {
122122
janetc_emit(c,
123-
(dest << 16) |
124-
(dest << 8) |
123+
((uint32_t) dest << 16) |
124+
((uint32_t) dest << 8) |
125125
JOP_GET_INDEX);
126126
}
127127
} else if (src.envindex >= 0) {
@@ -147,15 +147,15 @@ static void janetc_moveback(JanetCompiler *c,
147147
int32_t refreg = janetc_regalloc_temp(&c->scope->ra, JANETC_REGTEMP_5);
148148
janetc_loadconst(c, dest.constant, refreg);
149149
janetc_emit(c,
150-
(src << 16) |
151-
(refreg << 8) |
150+
((uint32_t) src << 16) |
151+
((uint32_t) refreg << 8) |
152152
JOP_PUT_INDEX);
153153
janetc_regalloc_freetemp(&c->scope->ra, refreg, JANETC_REGTEMP_5);
154154
} else if (dest.envindex >= 0) {
155155
/* Convert src to near reg */
156156
if (src > 255) {
157157
int32_t newsrc = JANETC_REGTEMP_5 + 0xF0;
158-
janetc_emit(c, JOP_MOVE_NEAR | ((uint32_t)(src) << 16) | (newsrc << 8));
158+
janetc_emit(c, JOP_MOVE_NEAR | ((uint32_t)(src) << 16) | ((uint32_t) newsrc << 8));
159159
src = newsrc;
160160
}
161161
janetc_emit(c,
@@ -199,7 +199,7 @@ static int32_t janetc_regfar(JanetCompiler *c, JanetSlot s, JanetcRegisterTemp t
199199
janetc_movenear(c, nearreg, s);
200200
if (nearreg >= 0xF0) {
201201
reg = janetc_allocfar(c);
202-
janetc_emit(c, JOP_MOVE_FAR | (nearreg << 8) | (reg << 16));
202+
janetc_emit(c, JOP_MOVE_FAR | ((uint32_t) nearreg << 8) | ((uint32_t) reg << 16));
203203
janetc_regalloc_freetemp(&c->scope->ra, nearreg, tag);
204204
} else {
205205
reg = nearreg;
@@ -268,7 +268,7 @@ void janetc_copy(
268268
static int32_t emit1s(JanetCompiler *c, uint8_t op, JanetSlot s, int32_t rest, int wr) {
269269
int32_t reg = janetc_regnear(c, s, JANETC_REGTEMP_0);
270270
int32_t label = janet_v_count(c->buffer);
271-
janetc_emit(c, op | (reg << 8) | ((uint32_t)rest << 16));
271+
janetc_emit(c, op | ((uint32_t) reg << 8) | ((uint32_t) rest << 16));
272272
if (wr)
273273
janetc_moveback(c, s, reg);
274274
janetc_free_regnear(c, s, reg, JANETC_REGTEMP_0);
@@ -278,7 +278,7 @@ static int32_t emit1s(JanetCompiler *c, uint8_t op, JanetSlot s, int32_t rest, i
278278
int32_t janetc_emit_s(JanetCompiler *c, uint8_t op, JanetSlot s, int wr) {
279279
int32_t reg = janetc_regfar(c, s, JANETC_REGTEMP_0);
280280
int32_t label = janet_v_count(c->buffer);
281-
janetc_emit(c, op | (reg << 8));
281+
janetc_emit(c, op | ((uint32_t) reg << 8));
282282
if (wr)
283283
janetc_moveback(c, s, reg);
284284
janetc_free_regnear(c, s, reg, JANETC_REGTEMP_0);
@@ -310,7 +310,7 @@ static int32_t emit2s(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2,
310310
int32_t reg1 = janetc_regnear(c, s1, JANETC_REGTEMP_0);
311311
int32_t reg2 = janetc_regnear(c, s2, JANETC_REGTEMP_1);
312312
int32_t label = janet_v_count(c->buffer);
313-
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16) | ((uint32_t)rest << 24));
313+
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16) | ((uint32_t)rest << 24));
314314
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
315315
if (wr)
316316
janetc_moveback(c, s1, reg1);
@@ -322,7 +322,7 @@ int32_t janetc_emit_ss(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2,
322322
int32_t reg1 = janetc_regnear(c, s1, JANETC_REGTEMP_0);
323323
int32_t reg2 = janetc_regfar(c, s2, JANETC_REGTEMP_1);
324324
int32_t label = janet_v_count(c->buffer);
325-
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16));
325+
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16));
326326
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
327327
if (wr)
328328
janetc_moveback(c, s1, reg1);
@@ -343,7 +343,7 @@ int32_t janetc_emit_sss(JanetCompiler *c, uint8_t op, JanetSlot s1, JanetSlot s2
343343
int32_t reg2 = janetc_regnear(c, s2, JANETC_REGTEMP_1);
344344
int32_t reg3 = janetc_regnear(c, s3, JANETC_REGTEMP_2);
345345
int32_t label = janet_v_count(c->buffer);
346-
janetc_emit(c, op | (reg1 << 8) | (reg2 << 16) | ((uint32_t)reg3 << 24));
346+
janetc_emit(c, op | ((uint32_t) reg1 << 8) | ((uint32_t) reg2 << 16) | ((uint32_t) reg3 << 24));
347347
janetc_free_regnear(c, s2, reg2, JANETC_REGTEMP_1);
348348
janetc_free_regnear(c, s3, reg3, JANETC_REGTEMP_2);
349349
if (wr)

src/core/specials.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,10 @@ static JanetSlot janetc_if(JanetFopts opts, int32_t argn, const Janet *argv) {
723723
labeld = janet_v_count(c->buffer);
724724
if (labeljr < labeld) {
725725
check_16bit_jump(c, labeljr, labelr);
726-
c->buffer[labeljr] |= (labelr - labeljr) << 16;
726+
c->buffer[labeljr] |= (uint32_t) (labelr - labeljr) << 16;
727727
if (!tail && labeljd < labeld) {
728728
check_24bit_jump(c, labeljd, labeld);
729-
c->buffer[labeljd] |= (labeld - labeljd) << 8;
729+
c->buffer[labeljd] |= (uint32_t) (labeld - labeljd) << 8;
730730
}
731731
}
732732

@@ -945,8 +945,8 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
945945
}
946946
/* But now add tail recursion */
947947
int32_t tempself = janetc_regalloc_temp(&tempscope.ra, JANETC_REGTEMP_0);
948-
janetc_emit(c, JOP_LOAD_SELF | (tempself << 8));
949-
janetc_emit(c, JOP_TAILCALL | (tempself << 8));
948+
janetc_emit(c, JOP_LOAD_SELF | ((uint32_t) tempself << 8));
949+
janetc_emit(c, JOP_TAILCALL | ((uint32_t) tempself << 8));
950950
janetc_regalloc_freetemp(&c->scope->ra, tempself, JANETC_REGTEMP_0);
951951
/* Compile function */
952952
JanetFuncDef *def = janetc_pop_funcdef(c);
@@ -955,8 +955,8 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
955955
int32_t defindex = janetc_addfuncdef(c, def);
956956
/* And then load the closure and call it. */
957957
int32_t cloreg = janetc_regalloc_temp(&c->scope->ra, JANETC_REGTEMP_0);
958-
janetc_emit(c, JOP_CLOSURE | (cloreg << 8) | (defindex << 16));
959-
janetc_emit(c, JOP_CALL | (cloreg << 8) | (cloreg << 16));
958+
janetc_emit(c, JOP_CLOSURE | ((uint32_t) cloreg << 8) | ((uint32_t) defindex << 16));
959+
janetc_emit(c, JOP_CALL | ((uint32_t) cloreg << 8) | ((uint32_t) cloreg << 16));
960960
janetc_regalloc_freetemp(&c->scope->ra, cloreg, JANETC_REGTEMP_0);
961961
c->scope->flags |= JANET_SCOPE_CLOSURE;
962962
return janetc_cslot(janet_wrap_nil());
@@ -980,7 +980,7 @@ static JanetSlot janetc_while(JanetFopts opts, int32_t argn, const Janet *argv)
980980
for (int32_t i = labelwt; i < labeld; i++) {
981981
if (c->buffer[i] == (0x80 | JOP_JUMP)) {
982982
check_24bit_jump(c, i, labeld);
983-
c->buffer[i] = JOP_JUMP | ((labeld - i) << 8);
983+
c->buffer[i] = JOP_JUMP | ((uint32_t) (labeld - i) << 8);
984984
}
985985
}
986986

test/suite-compile.janet

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,4 +156,6 @@
156156
(check-lint-compile '(let [outer1 "b"] outer1) "shadow local-to-global")
157157
(check-lint-compile '(do (def x "b") (def x "c")) "shadow local-to-local")
158158

159+
(check-lint-compile '(def [xxx [xxx yyy]] [1 [2 3]]) "shadow global-to-global one form")
160+
159161
(end-suite)

test/suite-corelib.janet

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,4 +207,6 @@
207207
'(fn :short-fn [] (set (my-table [2 1]) (quote foo))))
208208
"Macro expand inside set preserves tuple type correctly")
209209

210+
(assert-error "no infinite step range" (range 3 3 math/inf))
211+
210212
(end-suite)

0 commit comments

Comments
 (0)