Const slice indexing was not bounds checked.

This commit is contained in:
Christoffer Lerno
2025-07-03 23:53:01 +02:00
parent 759bc1d909
commit a46f73ad24
4 changed files with 19 additions and 21 deletions

View File

@@ -22,6 +22,7 @@
- `$for` ct-state not properly popped. - `$for` ct-state not properly popped.
- Inline `r / complex` for complex numbers fixed. - Inline `r / complex` for complex numbers fixed.
- Const slice lengths were not always detected as constant. - Const slice lengths were not always detected as constant.
- Const slice indexing was not bounds checked.
### Stdlib changes ### Stdlib changes

View File

@@ -12,17 +12,7 @@ ArrayIndex sema_len_from_const(Expr *expr)
// We also handle the case where we have a cast from a const array. // We also handle the case where we have a cast from a const array.
if (!sema_cast_const(expr)) if (!sema_cast_const(expr))
{ {
Type *flat = type_flatten(expr->type); if (type_flatten(expr->type)->type_kind != TYPE_SLICE) return -1;
switch (flat->type_kind)
{
case TYPE_ARRAY:
case TYPE_VECTOR:
return flat->array.len;
case TYPE_SLICE:
break;
default:
return -1;
}
if (expr->expr_kind == EXPR_SLICE) if (expr->expr_kind == EXPR_SLICE)
{ {
return range_const_len(&expr->slice_expr.range); return range_const_len(&expr->slice_expr.range);

View File

@@ -3887,24 +3887,25 @@ static inline bool sema_expr_analyse_subscript(SemaContext *context, Expr *expr,
RETURN_SEMA_ERROR(index, "Index is out of range."); RETURN_SEMA_ERROR(index, "Index is out of range.");
} }
ArraySize idx = index->const_expr.ixx.i.low; ArraySize idx = index->const_expr.ixx.i.low;
ArrayIndex len = sema_len_from_const(current_expr);
if (idx > len || (idx == len && !start_from_end) || (idx == 0 && start_from_end))
{
if (check_valid) goto VALID_FAIL_POISON;
RETURN_SEMA_ERROR(index, "The index (%s%llu) is out of range, the length is just %llu.",
start_from_end ? "^" : "",
(unsigned long long)idx,
(unsigned long long)len);
}
if (!is_const_initializer) if (!is_const_initializer)
{ {
// Handle bytes / String // Handle bytes / String
ArraySize len = current_expr->const_expr.bytes.len;
if (idx > len || (idx == len && !start_from_end) || (idx == 0 && start_from_end))
{
if (check_valid) goto VALID_FAIL_POISON;
RETURN_SEMA_ERROR(index, "The index (%s%llu) is out of range, the length is just %llu.",
start_from_end ? "^" : "",
(unsigned long long)idx,
(unsigned long long)current_expr->const_expr.bytes.len);
}
if (start_from_end) idx = len - idx; if (start_from_end) idx = len - idx;
unsigned char c = current_expr->const_expr.bytes.ptr[idx]; unsigned char c = current_expr->const_expr.bytes.ptr[idx];
expr_rewrite_const_int(expr, type_char, c); expr_rewrite_const_int(expr, type_char, c);
expr->type = type_char; expr->type = type_char;
return true; return true;
} }
if (sema_subscript_rewrite_index_const_list(current_expr, idx, start_from_end, expr)) return true; if (sema_subscript_rewrite_index_const_list(current_expr, idx, start_from_end, expr)) return true;
} }
} }
@@ -5889,7 +5890,7 @@ CHECK_DEEPER:
// 9. Fix hard coded function `len` on slices and arrays // 9. Fix hard coded function `len` on slices and arrays
if (kw == kw_len) if (kw == kw_len)
{ {
ArrayIndex index = sema_len_from_const(current_parent); ArrayIndex index = sema_len_from_expr(current_parent);
if (index > -1) if (index > -1)
{ {
expr_rewrite_const_int(expr, type_isz, index); expr_rewrite_const_int(expr, type_isz, index);

View File

@@ -0,0 +1,6 @@
fn int main()
{
const char[] ARR = { 1, 2, 3, 4, 5 };
$echo $defined(ARR[5]);
return 0;
}