Skip to content

Signed Integer Overflow in json_ipow #67

Description

@maxmlz

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:

lib/json.h

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.

harness.c

crash.json

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 🍺

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions