Skip to content

feat: decoder hardening with proper errors#1

Merged
Fyzu merged 1 commit into
mainfrom
decoder-hardening
Jun 2, 2026
Merged

feat: decoder hardening with proper errors#1
Fyzu merged 1 commit into
mainfrom
decoder-hardening

Conversation

@Fyzu
Copy link
Copy Markdown
Contributor

@Fyzu Fyzu commented Jun 2, 2026

Decoder hardening for untrusted JSON input:

  • Cap Struct/Value/ListValue recursion at 100 (matching protobuf's CodedInputStream / JsonFormat limit) so deeply nested input fails with a clean JSONException instead of StackOverflowError.
  • Normalize decode errors to fastjson2's native JSONException with position context (offset/line/column): malformed int64/uint64/float/double, timestamp, duration, base64, enum names, and numeric/bool map keys. Keep internal/config errors (missing TypeRegistry, bad target Class, unreachable invariants) as IllegalState/IllegalArgumentException so a config bug never masquerades as bad input. For Any, a missing registry is a config error (IllegalStateException) while a client-submitted unresolvable @type is user-facing (JSONException + position).
  • Any @type-first fast path: resolve the content descriptor up front and decode the remaining fields straight off the live reader, skipping the LinkedHashMap buffer + JSON.toJSONString + re-parse the old path required.
  • Validate bool map keys ("true"/"false" only) instead of silently coercing any string to false (which also collided keys).
  • Guard a null/missing packed-WKT "value" in an Any (previously an uncaught NullPointerException for Timestamp/Duration/BytesValue); google.protobuf.Value with null becomes NullValue, mirroring the top-level field rule.
  • Route generated decoders' bytes/enum/numeric+bool map-key parsing through public FieldReader helpers so codegen shares the identical JSONException contract (no inline BASE64.decode / Enum.valueOf / Long.parseLong).

Add BuffJsonHardeningTest (recursion depth, parse-error offsets, Any field-order parity, native error types, packed-WKT null value, bool map keys), validating codegen and runtime paths. Full suite green; decode throughput on par with prior baselines and encoder allocation within committed budgets.

Decoder hardening for untrusted JSON input:
- Cap Struct/Value/ListValue recursion at 100 (matching protobuf's
  CodedInputStream / JsonFormat limit) so deeply nested input fails with a
  clean JSONException instead of StackOverflowError.
- Normalize decode errors to fastjson2's native JSONException with position
  context (offset/line/column): malformed int64/uint64/float/double,
  timestamp, duration, base64, enum names, and numeric/bool map keys. Keep
  internal/config errors (missing TypeRegistry, bad target Class, unreachable
  invariants) as IllegalState/IllegalArgumentException so a config bug never
  masquerades as bad input. For Any, a missing registry is a config error
  (IllegalStateException) while a client-submitted unresolvable @type is
  user-facing (JSONException + position).
- Any @type-first fast path: resolve the content descriptor up front and decode
  the remaining fields straight off the live reader, skipping the
  LinkedHashMap buffer + JSON.toJSONString + re-parse the old path required.
- Validate bool map keys ("true"/"false" only) instead of silently coercing
  any string to false (which also collided keys).
- Guard a null/missing packed-WKT "value" in an Any (previously an uncaught
  NullPointerException for Timestamp/Duration/BytesValue); google.protobuf.Value
  with null becomes NullValue, mirroring the top-level field rule.
- Route generated decoders' bytes/enum/numeric+bool map-key parsing through
  public FieldReader helpers so codegen shares the identical JSONException
  contract (no inline BASE64.decode / Enum.valueOf / Long.parseLong).

Add BuffJsonHardeningTest (recursion depth, parse-error offsets, Any field-order
parity, native error types, packed-WKT null value, bool map keys), validating
codegen and runtime paths. Full suite green; decode throughput on par with prior
baselines and encoder allocation within committed budgets.
@Fyzu Fyzu merged commit 9662073 into main Jun 2, 2026
2 checks passed
@Fyzu Fyzu deleted the decoder-hardening branch June 2, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant