Skip to content

Fixed malformed-number parsing (#31) and added java.time mapper support (#23)#32

Open
Kitty-Hivens wants to merge 4 commits into
JavaWebStack:devfrom
Kitty-Hivens:dev
Open

Fixed malformed-number parsing (#31) and added java.time mapper support (#23)#32
Kitty-Hivens wants to merge 4 commits into
JavaWebStack:devfrom
Kitty-Hivens:dev

Conversation

@Kitty-Hivens

@Kitty-Hivens Kitty-Hivens commented Jun 9, 2026

Copy link
Copy Markdown

This PR bundles two independent changes.

JSON parser: malformed numbers (#31)

parseNumber now validates the candidate token without consuming it and returns null on failure, so the existing error path reports a proper ParseException at the offending position instead of leaking a NumberFormatException. Exponent-only numbers (e.g. 1e3), previously routed to Long.parseLong and failing, now parse as doubles.

Mapper: java.time support (#23)

A new JavaTimeMapper (sibling of DateMapper, registered in DefaultMappers) maps the core java.time types: LocalDate, LocalDateTime, LocalTime, Instant, OffsetDateTime, ZonedDateTime, OffsetTime, Year, YearMonth, MonthDay. Values serialize to their canonical ISO-8601 form by default. The existing @DateFormat annotation still applies: a custom pattern uses DateTimeFormatter syntax, and epoch mode is supported for Instant only (any other type throws a MapperException rather than silently dropping the zone/offset). No public API or Java language level change (target stays 8).

Out of scope, as separate follow-ups: Duration / Period / ZoneId / ZoneOffset, and java.time support in the BSON converter.

Test plan

  • mvn test green.
  • JsonParserTest: added malformed-number cases (--, -, 1.2.3, 12e, .) asserting ParseException, plus scientific notation (1e3, 2.5E-2).
  • JavaTimeMapperTest: ISO round-trip for all 10 types, epoch Instant (seconds/millis), custom pattern, epoch rejection on a non-Instant type, and malformed input -> MapperException.

… parser (JavaWebStack#31)

parseNumber now validates the candidate token without consuming it and returns null on failure, so the existing error path reports a proper ParseException at the offending position instead of leaking a NumberFormatException. Also fixed exponent-only numbers (e.g. 1e3) being routed to Long.parseLong and failing.
New JavaTimeMapper handles LocalDate, LocalDateTime, LocalTime, Instant, OffsetDateTime, ZonedDateTime, OffsetTime, Year, YearMonth and MonthDay. Values serialize to their canonical ISO-8601 form by default; @DateFormat still applies -- a custom pattern (DateTimeFormatter syntax) or epoch mode (Instant only, otherwise a MapperException). Registered as a sibling of DateMapper, no public API or Java language level change.
@Kitty-Hivens Kitty-Hivens changed the title Fixed malformed numbers leaking a NumberFormatException from the JSON parser (#31) Fixed malformed-number parsing (#31) and added java.time mapper support (#23) Jun 9, 2026
@x7airworker x7airworker requested a review from Copilot June 25, 2026 18:34

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR bundles (1) a fix to JSON number parsing so malformed numeric tokens surface as ParseException rather than leaking NumberFormatException, and (2) new java.time type mapping support integrated into the default mapper set.

Changes:

  • Updated JsonParser.parseNumber() to validate candidate numeric tokens and avoid leaking NumberFormatException, including support for scientific notation.
  • Added a JavaTimeMapper registered in DefaultMappers to map core java.time types with ISO-8601 defaults plus @DateFormat pattern/epoch options (epoch restricted to Instant).
  • Added JUnit tests for malformed/scientific-number parsing and java.time mapper round-trips / error cases.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/main/java/org/javawebstack/abstractdata/json/JsonParser.java Adjusts number token handling to prevent NumberFormatException leaks and support exponent notation.
src/main/java/org/javawebstack/abstractdata/mapper/DefaultMappers.java Registers and implements JavaTimeMapper to support mapping of key java.time types.
src/test/java/org/javawebstack/abstractdata/json/JsonParserTest.java Adds tests for malformed numbers and scientific notation parsing.
src/test/java/org/javawebstack/abstractdata/mapper/JavaTimeMapperTest.java Adds coverage for ISO round-trips, epoch Instant, custom patterns, and malformed-input failures.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main/java/org/javawebstack/abstractdata/json/JsonParser.java Outdated
…input

fromAbstract rebuilt its failure message with element.string(), which itself throws AbstractCoercingException for object/array input and escaped the intended MapperException; a safe representation is now captured before the try and reused in the catch.

A custom @DateFormat pattern on an Instant was written through a UTC-defaulted formatter but read back through a zone-less one, so deserializing the value it had just serialized threw; the read side now applies the same UTC default.

Add round-trip coverage for Instant custom patterns and for non-primitive input.
parseNumber rejected an invalid token without consuming anything, so parse() flagged the error at the token start ('1' for "1.2.3") rather than at the character that actually broke parsing.

It now consumes the longest valid numeric prefix before returning null, leaving the offending character as the stack head for the position report. The token is still rejected as a whole; the shared parse logic moved into toNumber().
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.

2 participants