Merge pull request #301 from kichikuou/sort-strarray

Fix use-after-free in custom string array sort
This commit is contained in:
Nunuhara Cabbage
2026-02-16 20:35:02 -08:00
committed by GitHub
3 changed files with 38 additions and 1 deletions
+13 -1
View File
@@ -557,6 +557,17 @@ static int array_compare_custom(const void *_a, const void *_b)
return d ? d : a->index - b->index;
}
static int array_compare_custom_string(const void *_a, const void *_b)
{
const struct sortable *a = _a;
const struct sortable *b = _b;
stack_push(vm_string_ref(heap_get_string(a->v.i)));
stack_push(vm_string_ref(heap_get_string(b->v.i)));
vm_call(current_sort_function, -1);
int d = stack_pop().i;
return d ? d : a->index - b->index;
}
void array_sort(struct page *page, int compare_fno)
{
if (!page)
@@ -569,7 +580,8 @@ void array_sort(struct page *page, int compare_fno)
values[i].index = i;
}
current_sort_function = compare_fno;
qsort(values, page->nr_vars, sizeof(struct sortable), array_compare_custom);
qsort(values, page->nr_vars, sizeof(struct sortable),
page->a_type == AIN_ARRAY_STRING ? array_compare_custom_string : array_compare_custom);
for (int i = 0; i < page->nr_vars; i++) {
page->values[i] = values[i].v;
}
BIN
View File
Binary file not shown.
+25
View File
@@ -233,6 +233,30 @@ void test_array_sort_custom(void)
test_bool("array.Sort()", !failed, true);
}
int compare_string(string a, string b)
{
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
void test_array_sort_custom_string(void)
{
int i;
bool failed = false;
array@string ar;
ar.PushBack("4");
ar.PushBack("1");
ar.PushBack("3");
ar.PushBack("0");
ar.PushBack("2");
ar.Sort(&compare_string);
for (i = 0; i < 5 && !failed; i++) {
failed = ar[i] != "%d" % i;
}
test_bool("string_array.Sort()", !failed, true);
}
int ctor_ctr = 0;
struct array_ctor {
@@ -285,6 +309,7 @@ void test_arrays(void)
test_array_sort_float();
test_array_sort_string();
test_array_sort_custom();
test_array_sort_custom_string();
test_array_constructors();
test_array_push_struct_with_ref();
}