Ghost Serialization 1.2.0 Latest
·
520 commits
to main
since this release
This release introduces native, declarative network annotations (@GhostStrict and @GhostCoerce) across all major HTTP integrations (Retrofit, Spring Boot, and Ktor), implements critical security and boundary bug fixes with zero-allocation performance preservation, and recovers maximum lenient parsing throughput by default in all network adapters.
🚀 What's New
🛠️ Declarative Network Customization
- Native Declarative Annotations (
@GhostStrict&@GhostCoerce): Shipped new dynamic annotations for elegant, declarative, and zero-allocation parsing customization:- Retrofit: Fully supports
@GhostStrictand@GhostCoerceon API service interface methods to customize parser configurations dynamically per endpoint. - Spring Boot (Spring WebMvc): Integrates native thread-safe annotation scanning using
RequestBodyAdvice. Supports@GhostStrictand@GhostCoerceat the controller class, endpoint method, or@RequestBodyparameter levels out-of-the-box. - Ktor (KMP): Enhanced the
GhostContentConverteringhost-ktorwith a customconfigurerlambda parameter, enabling developers to dynamically tune or enforce strict/coerced settings directly in their KMPContentNegotiationpipelines.
- Retrofit: Fully supports
🛠️ What's Changed
🛡️ Core Security & Resilience Fixes
- Scientific Notation Exponent Integer Overflow: Fixed a vulnerability in
parseExponentValuefor flat and streaming readers by clamping exponent values exceeding1000to prevent integer overflows. - Geometric Capacity Overflow Protection: Fixed a potential buffer overflow vulnerability in
FlatByteArrayWriter.ensureCapacityby safely catching integer overflows and clamping growth boundaries toInt.MAX_VALUE. - Dynamic Key Hash Collision mixing: Eliminated perfect hash collision vulnerabilities in
JsonReaderOptionsand reader subsystems by dynamically detecting perfect key collisions at initialization and conditionally applying a branchless last-byte mix. - Serializer Delegation Config Preservation: Fixed a configuration propagation leak in the
GhostSerializer.deserialize(GhostJsonFlatReader)default delegation method by copying all configuration attributes (e.g.strictMode,coerceStringsToNumbers) to the delegated streaming reader. - Negative Depth Boundary Safety: Protected reader depth decrement operations in
endObject()andendArray()to stay non-negative, preventing bitmask corruption under malformed or resilient parsing. - Unbounded Surrogate Parser Checks: Fixed a boundary bug in
GhostJsonReaderandGhostJsonFlatReaderStringswhere checking for trailing unicode surrogate pairs at the end of truncated strings causedIndexOutOfBoundsExceptioninstead of structuredGhostJsonException. - Long Overflow Check: Fixed a silent overflow bug in
calculateLongWithOverflowCheckwhere values matchingLong.MIN_VALUEwith additional trailing digits bypassed overflow verification.
⚙️ Parser & Writer Correctness
- Strict Comma Validation: Enforced strict JSON comma checking in both streaming and flat readers using zero-allocation bitwise mask tracking. Bound strictly to
strictMode = trueto preserve maximum lenient parsing speed by default. - Iterative Comma Synchronization in
hasNext(): Fixed a critical parser state leak inhasNext()wherecommaConsumedMaskandneedsCommaMaskwere not correctly cleared and tracked during iterative loops likeskipValue(). - Select Separator Comma Synchronization: Fixed
internalSelectin both flat and streaming readers to correctly synchronize and clearcommaConsumedMaskwhen a separator comma is consumed, resolving unexpected comma errors in subsequent field decodes. - Strict Byte Checking: Resolved a project rule violation in
expectByteby replacing the prohibitedtoChar()extension method with the directChar(expected)constructor path. - Negative Zero Sign Loss: Corrected double formatting in
GhostDoubleFormatterto preserve the minus sign for-0.0by performing a zero-copy raw bits sign check. - Double Formatter Precision Threshold: Lowered
MASSIVE_DOUBLE_THRESHOLDfrom1e15to1e9inGhostDoubleFormatterto guarantee standard-compliant shortest representation. - Leading Zero Shift Masking: Corrected a shift-masking bug in
validateLeadingZerowhere non-digit characters in the ASCII range of112..121were validated as digits. - Flat Writer Infinite Loop: Fixed an infinite loop in
ensureCapacitywhenFlatByteArrayWriterwas initialized with zero capacity. - Primitive Collection Doubling: Fixed an
ArrayIndexOutOfBoundsExceptioninGhostIntListandGhostLongListwhen initialized with zero capacity.
⚡ Performance & Allocation Optimization
- Zero-Allocation Stream Decoding: In
StreamingGhostSource.decodeToString, eliminated a temporaryBufferallocation and segment copy. Now leverages Okio'ssnapshot(end).substring(start, end).utf8()directly, resulting in zero-copy range views of existing buffered segments. - Pool Tier Collision: Resolved a collision in
GhostPools.ktwhereSCRATCH_BUFFER_SIZE(48 bytes) andTIER_SMALL(1024 bytes) shared the same pool slot. Added a dedicatedscratchfield toGhostPoolto prevent buffer eviction leaks.
🐘 Compiler (KSP) & Gradle
- Non-Nested Sealed Subclasses: Enhanced KSP generation to scan
superTypesfor sealed parents. This ensures that non-nested/top-level sealed subclasses correctly serialize and deserialize their type discriminator key. - Gradle Plugin KSP Setup Order: Refactored KSP compiler dependency injection in the Gradle plugin to be completely order-independent and reactive to KSP and KMP target application sequences.
📚 Documentation
- Updated
README.mdandCHANGELOG.mdwith complete usage guides, annotations targets, and configuration examples for Retrofit, Spring Boot, and Ktor.