-
Notifications
You must be signed in to change notification settings - Fork 103
Signed Integer Overflow in json_ipow #67
Description
Hey my dude,
Great repository. Single header libraries are my favorite to review as well as use in my own projects. 😄
Finding
A signed integer overflow exists in json_ipow. The function declares its base parameter as int, allowing the squaring step base *= base in the binary-exponentiation loop to silently overflow when the intermediate base value reaches 10^8 (iteration 4 for any initial base = 10 and exp >= 16).
json_ipow implements binary (fast) exponentiation. In every loop iteration - including the final one, where the squared result is never used - the squaring base *= base is performed unconditionally:
Lines 706 to 717 in 5a3f3ab
| JSON_INTERN json_number | |
| json_ipow(int base, unsigned exp) | |
| { | |
| /* simple power function for json exponent numbers */ | |
| long res = 1; | |
| while (exp) { | |
| if (exp & 1) | |
| res *= base; | |
| exp >>= 1; | |
| base *= base; | |
| } return (json_number)res; | |
| } |
With base = 10 and exp = 22:
| Iteration | exp & 1 | Action on res | exp after >>= 1 | base after *= base |
|---|---|---|---|---|
| 1 | 0 | — | 11 | 100 |
| 2 | 1 | res = 100 | 5 | 10 000 |
| 3 | 1 | res = 1 000 000 | 2 | 100 000 000 |
| 4 | 0 | — | 1 | 10^16 → OVERFLOW |
| 5 | 1 | res *= garbage | 0 | (loop exits) |
100000000 * 100000000 = 10^16 exceeds INT_MAX = 2,147,483,647 ≈ 2.1×10^9.
In an uninstrumented production build the multiplication wraps silently, producing a garbage base value that propagates into res, corrupting the number conversion result.
Steps to Reproduce
I have attached the crashing input as well as a test harness.
Compile harness.c with the following:
$ clang -g -fsanitize=address,undefined \
-fno-omit-frame-pointer \
-fsanitize-recover=all \
-o harness harness.c
Then run the harness with the crashing input:
$ ./harness crash.json
../lib/json.h:715:14: runtime error: signed integer overflow: 100000000 * 100000000 cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../lib/json.h:715:14
json_convert result: 1.31244e+16
Environment
- vurtun / lib version:
5a3f3aba052e63ffae8eb0214c6bb8ffffedea3c - System info:
Linux kali 6.18.12+kali-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.18.12-1kali1 (2026-02-25) x86_64 GNU/Linux - Compiler:
Debian clang version 19.1.7
Cheers mate 🍺