Commit 4e91729
authored
fix(ustring): protect against idempotent rehash upon collision (#5090)
Some fuzzing stumbled across a very interesting edge case in the
rehashing logic of ustring internals:
If the initial hash location of a newly ustring-ized string is already
occupied, it rehashes. But we never considered what happens if it ends
up rehashing to the same slot! And in fact, that can happen if the true
hash is 0 (I'm not sure if it can/does for any other value). And we may
have thought that the only string that would ever hash to 0 is the empty
string (which is 0 hash by design, and doesn't need to rehash because
the table is seeded with that entry already in its correct slot).
So anyway, if there was some other string that happened to hash to 0, it
would get caught in an infinite loop of rehashing but never finding a
free slot, because it keeps rehashing to the very same occupied slot.
And would you believe that there IS such a string, and it is this one:
"\t\n\n\t\301\350`O\217c85?\202\200\251r|}\304\351\2517\337K'\217C\240"
(unprintable chars expressed as escaped octal values)
The crux of this patch is to notice when the old and new hash bit
pattern has not changed, and bump it by 7 (a prime number, so it should
not land on the same location again until every slot in the bin has been
exhausted).
Solution entirely from my own human brain, in case you're wondering.
Signed-off-by: Larry Gritz <lg@larrygritz.com>1 parent 9c7b98c commit 4e91729
2 files changed
+27
-4
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
522 | 522 | | |
523 | 523 | | |
524 | 524 | | |
525 | | - | |
| 525 | + | |
526 | 526 | | |
527 | 527 | | |
528 | 528 | | |
| |||
546 | 546 | | |
547 | 547 | | |
548 | 548 | | |
549 | | - | |
550 | | - | |
551 | | - | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
552 | 566 | | |
553 | 567 | | |
554 | 568 | | |
555 | 569 | | |
556 | 570 | | |
557 | 571 | | |
558 | 572 | | |
| 573 | + | |
559 | 574 | | |
560 | 575 | | |
561 | 576 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
173 | 173 | | |
174 | 174 | | |
175 | 175 | | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
176 | 184 | | |
177 | 185 | | |
178 | 186 | | |
| |||
0 commit comments