From 79916534226bfd33e28f70f86193988c944b93f4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 18:16:37 +0000 Subject: [PATCH] Correct two stale comments in the jsonpull port jsonpull.h said a json_number is 40 bytes; it is 32 (json_object is 24, and the repr discriminator fits in the base class's tail padding, so the 8-byte union lands at offset 24). plugin.cpp's parse_feature() said `j` is freed only just before returning or as jp->root at end of stream, but there is a third json_free(j) at the bottom of the loop, for a complete Feature whose geometry came out empty. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_017KNxyHKasyWrWcvre2yK4r --- jsonpull/jsonpull.h | 2 +- plugin.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/jsonpull/jsonpull.h b/jsonpull/jsonpull.h index 059dde0d..7b6a6ac8 100644 --- a/jsonpull/jsonpull.h +++ b/jsonpull/jsonpull.h @@ -111,7 +111,7 @@ struct json_object { inline const std::string &string() const; // Numbers are stored in a discriminated union (double / unsigned / - // signed) so a json_number is only 40 bytes instead of 48. The + // signed) so a json_number is only 32 bytes instead of 48. The // large_*() accessors return 0 when the number is not currently // stored in that representation, matching the prior convention // where "0" meant "not set, fall through to the next slot". diff --git a/plugin.cpp b/plugin.cpp index 7e07dea3..159c38c7 100644 --- a/plugin.cpp +++ b/plugin.cpp @@ -151,9 +151,11 @@ serial_feature parse_feature(json_pull_ptr &jp, int z, unsigned x, unsigned y, s // intermediate (still incomplete) container nodes. We must NOT free // these intermediates here: they belong to the larger feature hash // still being assembled, and freeing them would splice them out of - // the parent and corrupt the in-progress tree. We only free `j` - // after we have successfully processed a complete Feature hash - // (just before returning), or `jp->root` when the stream ends. + // the parent and corrupt the in-progress tree. So the `continue` + // paths below all leave `j` alone; `j` is only freed once it is a + // complete Feature hash -- either just before returning it, or at + // the bottom of the loop if its geometry turned out to be empty -- + // or as `jp->root` when the stream ends. json_object *j = json_read(jp); if (j == nullptr) { if (jp->error != nullptr) {