From 34fc22a7c22777ca26b01b760e468c24e911492a Mon Sep 17 00:00:00 2001 From: Weaselbot Date: Mon, 29 Jun 2026 13:53:31 -0400 Subject: [PATCH] Handle null parser in WeaselJsonParser_reset and _destroy WeaselJsonParser_create can return nullptr when allocation fails or the requested stack size is too small. Previously, passing that nullptr to WeaselJsonParser_reset or WeaselJsonParser_destroy dereferenced it before doing any work, causing immediate undefined behavior. Add an early null check to both functions so they behave like free(nullptr) (i.e., are a safe no-op). Also add a doctest case covering both a null returned from create and a literal nullptr. Closes #41 --- src/lib.cpp | 6 ++++++ src/test.cpp | 14 ++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/lib.cpp b/src/lib.cpp index cd1ea32..715f2c6 100644 --- a/src/lib.cpp +++ b/src/lib.cpp @@ -29,11 +29,17 @@ WeaselJsonParser_create(int stackSize, const WeaselJsonCallbacks *callbacks, __attribute__((visibility("default"))) void WeaselJsonParser_reset(WeaselJsonParser *parser) { + if (parser == nullptr) { + return; + } ((Parser3 *)parser)->reset(); } __attribute__((visibility("default"))) void WeaselJsonParser_destroy(WeaselJsonParser *parser) { + if (parser == nullptr) { + return; + } ((Parser3 *)parser)->~Parser3(); free(parser); } diff --git a/src/test.cpp b/src/test.cpp index eec6669..d13d353 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -246,6 +246,20 @@ TEST_CASE("create rejects too-small stack") { WeaselJsonParser_destroy(parser); } +TEST_CASE("reset and destroy accept null parser") { + // Creation can legitimately fail and return null. The cleanup functions must + // tolerate a null pointer the same way free(nullptr) is a no-op. + auto c = noopCallbacks(); + WeaselJsonParser *parser = WeaselJsonParser_create(-1, &c, nullptr, 0); + REQUIRE(parser == nullptr); + WeaselJsonParser_reset(parser); // must not crash + WeaselJsonParser_destroy(parser); // must not crash + + // Calling reset/destroy on literal nullptr directly must also be safe. + WeaselJsonParser_reset(nullptr); + WeaselJsonParser_destroy(nullptr); +} + TEST_CASE("parse rejects negative length") { auto c = noopCallbacks(); auto *parser = WeaselJsonParser_create(1024, &c, nullptr, 0);