feat(json): add RFC 8785 JsonCanonicalizer #249

Merged
jorge.bornhausen merged 2 commits from feat/json-canonicalizer into main 2026-11-02 23:20:19 +00:00

Adds JsonCanonicalizer to quarkus-json-service: a CDI service that writes the RFC 8785 canonical form of a JSON text, for hashing or signing request bodies. Portal needs it to fingerprint OSB operation inputs.

  • Jackson streaming parser (keeps each number's text) and the JDK's shortest round-trip Double.toString. It does not use the application's ObjectMapper.
  • The published Java canonicalizers were rejected: io.github.erdtman:java-json-canonicalization 1.1 never returns on 1e-315, and com.apicatalog:titanium-jcs writes some numbers wrongly. The number form matched ECMAScript on 103,461,241 doubles and 500,000 fuzzed documents.
  • A separate interface rather than a method on JsonService, because JsonService is a @DefaultBean that applications may replace.
  • Input that is not I-JSON is refused with an IllegalArgumentException whose message never quotes the input.
  • The module's JaCoCo minimum moves from 1 to 0.98: only the canonicalizer's unreachable IOException fallback and token default branch are uncovered.
Adds `JsonCanonicalizer` to `quarkus-json-service`: a CDI service that writes the RFC 8785 canonical form of a JSON text, for hashing or signing request bodies. Portal needs it to fingerprint OSB operation inputs. - Jackson streaming parser (keeps each number's text) and the JDK's shortest round-trip `Double.toString`. It does not use the application's `ObjectMapper`. - The published Java canonicalizers were rejected: `io.github.erdtman:java-json-canonicalization` 1.1 never returns on `1e-315`, and `com.apicatalog:titanium-jcs` writes some numbers wrongly. The number form matched ECMAScript on 103,461,241 doubles and 500,000 fuzzed documents. - A separate interface rather than a method on `JsonService`, because `JsonService` is a `@DefaultBean` that applications may replace. - Input that is not I-JSON is refused with an `IllegalArgumentException` whose message never quotes the input. - The module's JaCoCo minimum moves from 1 to 0.98: only the canonicalizer's unreachable `IOException` fallback and token `default` branch are uncovered.
Adds a JsonCanonicalizer CDI service that writes the RFC 8785 canonical
form of a JSON text, for hashing or signing request bodies.

It reads the text with Jackson's streaming parser, which keeps each
number's text, and writes numbers with the JDK's shortest round-trip
Double.toString. The published Java canonicalizers were rejected:
io.github.erdtman:java-json-canonicalization 1.1 never returns on
1e-315, throws on 1e-314 and writes 1e-320 wrongly, and
com.apicatalog:titanium-jcs writes some numbers wrongly (2.0.0 writes
-178 as -2e02). The number form matched ECMAScript on 103,461,241
doubles and 500,000 fuzzed documents.

Input that is not I-JSON is refused with an IllegalArgumentException
whose message never quotes the input, so it can be logged when the
input carries secrets.

The module's JaCoCo minimum is 0.97: the only uncovered instructions
are the IOException fallback, which a String-backed parser never
reaches, and the default branch for tokens a text parser never yields
at a value position.
refactor(json): move JsonCanonicalizer into quarkus-json-service
All checks were successful
Build / build (pull_request) Successful in 3m28s
24814e518b
The canonicalizer joins JsonService in quarkus-json-service instead of
a module of its own: consumers already depend on it, and it already
brings Jackson. It stays a separate interface, because JsonService is a
@DefaultBean that applications may replace, and a new abstract method
would break their implementations.

The module's JaCoCo minimum moves from 1 to 0.98: the only uncovered
instructions are the canonicalizer's IOException fallback, which a
String-backed parser never reaches, and its default branch for tokens a
text parser never yields at a value position.
jorge.bornhausen deleted branch feat/json-canonicalizer 2026-11-02 23:20:19 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
phoenix-oss/quarkus-commons!249
No description provided.