locale: Fix UB on VLA allocation

Both level 2 and level 3 sizes can be zero, which triggers a 0-size
VLA.  Reorganize the code to allocate the VLA iff sizes are positive.
This commit is contained in:
Adhemerval Zanella 2025-04-22 10:50:13 -03:00
parent b5a09ebb3f
commit eadfcdb2b9
2 changed files with 80 additions and 68 deletions

View File

@ -212,12 +212,13 @@ static void
CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t) CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t)
{ {
size_t i, j, k; size_t i, j, k;
uint32_t reorder3[t->level3_size];
uint32_t reorder2[t->level2_size];
uint32_t level2_offset, level3_offset, last_offset; uint32_t level2_offset, level3_offset, last_offset;
/* Uniquify level3 blocks. */ /* Uniquify level3 blocks. */
k = 0; k = 0;
if (t->level3_size > 0)
{
uint32_t reorder3[t->level3_size];
for (j = 0; j < t->level3_size; j++) for (j = 0; j < t->level3_size; j++)
{ {
for (i = 0; i < k; i++) for (i = 0; i < k; i++)
@ -234,14 +235,18 @@ CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t)
k++; k++;
} }
} }
t->level3_size = k;
for (i = 0; i < (t->level2_size << t->q); i++) for (i = 0; i < (t->level2_size << t->q); i++)
if (t->level2[i] != EMPTY) if (t->level2[i] != EMPTY)
t->level2[i] = reorder3[t->level2[i]]; t->level2[i] = reorder3[t->level2[i]];
}
t->level3_size = k;
/* Uniquify level2 blocks. */ /* Uniquify level2 blocks. */
k = 0; k = 0;
if (t->level2_size > 0)
{
uint32_t reorder2[t->level2_size];
for (j = 0; j < t->level2_size; j++) for (j = 0; j < t->level2_size; j++)
{ {
for (i = 0; i < k; i++) for (i = 0; i < k; i++)
@ -258,11 +263,12 @@ CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t)
k++; k++;
} }
} }
t->level2_size = k;
for (i = 0; i < t->level1_size; i++) for (i = 0; i < t->level1_size; i++)
if (t->level1[i] != EMPTY) if (t->level1[i] != EMPTY)
t->level1[i] = reorder2[t->level1[i]]; t->level1[i] = reorder2[t->level1[i]];
}
t->level2_size = k;
/* Create and fill the resulting compressed representation. */ /* Create and fill the resulting compressed representation. */
last_offset = last_offset =

View File

@ -3423,12 +3423,13 @@ static void
add_locale_wctype_table (struct locale_file *file, struct wctype_table *t) add_locale_wctype_table (struct locale_file *file, struct wctype_table *t)
{ {
size_t i, j, k; size_t i, j, k;
uint32_t reorder3[t->level3_size];
uint32_t reorder2[t->level2_size];
uint32_t level2_offset, level3_offset; uint32_t level2_offset, level3_offset;
/* Uniquify level3 blocks. */ /* Uniquify level3 blocks. */
k = 0; k = 0;
if (t->level3_size > 0)
{
uint32_t reorder3[t->level3_size];
for (j = 0; j < t->level3_size; j++) for (j = 0; j < t->level3_size; j++)
{ {
for (i = 0; i < k; i++) for (i = 0; i < k; i++)
@ -3445,14 +3446,18 @@ add_locale_wctype_table (struct locale_file *file, struct wctype_table *t)
k++; k++;
} }
} }
t->level3_size = k;
for (i = 0; i < (t->level2_size << t->q); i++) for (i = 0; i < (t->level2_size << t->q); i++)
if (t->level2[i] != EMPTY) if (t->level2[i] != EMPTY)
t->level2[i] = reorder3[t->level2[i]]; t->level2[i] = reorder3[t->level2[i]];
}
t->level3_size = k;
/* Uniquify level2 blocks. */ /* Uniquify level2 blocks. */
k = 0; k = 0;
if (t->level2_size > 0)
{
uint32_t reorder2[t->level2_size];
for (j = 0; j < t->level2_size; j++) for (j = 0; j < t->level2_size; j++)
{ {
for (i = 0; i < k; i++) for (i = 0; i < k; i++)
@ -3469,11 +3474,12 @@ add_locale_wctype_table (struct locale_file *file, struct wctype_table *t)
k++; k++;
} }
} }
t->level2_size = k;
for (i = 0; i < t->level1_size; i++) for (i = 0; i < t->level1_size; i++)
if (t->level1[i] != EMPTY) if (t->level1[i] != EMPTY)
t->level1[i] = reorder2[t->level1[i]]; t->level1[i] = reorder2[t->level1[i]];
}
t->level2_size = k;
t->result_size = t->result_size =
5 * sizeof (uint32_t) 5 * sizeof (uint32_t)