Skip to content

Commit e7958e2

Browse files
committed
Issue #118 fix upstream bug in JsonNumber.of(double) hardcoding offsets
Applied local workaround for upstream jdk-sandbox bug where JsonNumber.of(double) hardcodes decimalOffset=0 and exponentOffset=0, causing toLong() to fail for integral doubles like 123.0. Fix: delegate of(double) to of(String) which correctly computes offsets via Json.parse(). Added test TestJsonNumberOfDouble to verify the fix. To verify: mvn test -pl json-java21 -Dtest=TestJsonNumberOfDouble All 4 tests pass (toString, toDouble, toLong for integral, toLong throws for non-integral).
1 parent 85389ba commit e7958e2

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,12 @@ This is a simplified backport with the following changes from the original:
295295
- Removed `@PreviewFeature` annotations.
296296
- Compatible with JDK 21.
297297

298+
### Upstream Bug Fixes
299+
300+
The following fixes have been applied to address bugs in the upstream OpenJDK jdk-sandbox code. These are upstream issues that should be reported to the [core-libs-dev@openjdk.org](mailto:core-libs-dev@openjdk.org) mailing list per OpenJDK process:
301+
302+
- **`JsonNumber.of(double)` offset bug** ([#118](https://github.com/simbo1905/java.util.json.Java21/issues/118)): The upstream implementation hardcodes `decimalOffset=0` and `exponentOffset=0`, causing `toLong()` to fail for integral doubles like `123.0`. Our fix delegates to `JsonNumber.of(String)` which correctly computes offsets via `Json.parse()`.
303+
298304
## Security Considerations
299305

300306
**⚠️ This unstable API historically contained a undocumented security vulnerabilities.** The compatibility test suite (documented below) includes crafted attack vectors that expose these issues:

json-java21/src/main/java/jdk/sandbox/java/util/json/JsonNumber.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,11 @@ static JsonNumber of(double num) {
113113
if (!Double.isFinite(num)) {
114114
throw new IllegalArgumentException("Not a valid JSON number");
115115
}
116-
var str = Double.toString(num);
117-
return new JsonNumberImpl(str.toCharArray(), 0, str.length(), 0, 0);
116+
// LOCAL FIX for upstream bug: The original code hardcoded decimalOffset=0
117+
// and exponentOffset=0, which breaks toLong() for integral doubles like 123.0.
118+
// Delegating to of(String) ensures correct offset computation via Json.parse().
119+
// See: https://github.com/simbo1905/java.util.json.Java21/issues/118
120+
return JsonNumber.of(Double.toString(num));
118121
}
119122

120123
/**
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package jdk.sandbox.java.util.json;
2+
3+
import org.junit.jupiter.api.Test;
4+
import static org.assertj.core.api.Assertions.*;
5+
6+
public class TestJsonNumberOfDouble {
7+
8+
@Test
9+
void ofDoubleToStringPreservesValue() {
10+
var jn = JsonNumber.of(123.45);
11+
assertThat(jn.toString()).isEqualTo("123.45");
12+
}
13+
14+
@Test
15+
void ofDoubleToDoubleWorks() {
16+
var jn = JsonNumber.of(123.45);
17+
assertThat(jn.toDouble()).isEqualTo(123.45);
18+
}
19+
20+
@Test
21+
void ofDoubleThenToLongForIntegralDouble() {
22+
// 123.0 should be convertible to long 123
23+
var jn = JsonNumber.of(123.0);
24+
System.out.println("toString: " + jn.toString());
25+
assertThat(jn.toLong()).isEqualTo(123L);
26+
}
27+
28+
@Test
29+
void ofDoubleThenToLongForNonIntegralShouldThrow() {
30+
var jn = JsonNumber.of(123.45);
31+
assertThatThrownBy(() -> jn.toLong())
32+
.isInstanceOf(jdk.sandbox.java.util.json.JsonAssertionException.class);
33+
}
34+
}

0 commit comments

Comments
 (0)