WeaselJsonParser_parse crashes on null parser #51

Closed
opened 2026-07-05 00:45:01 +00:00 by weaselbot · 0 comments
Member

The public C API function WeaselJsonParser_parse casts the supplied pointer and dispatches directly without checking for null. Passing nullptr causes immediate undefined behavior (a null-pointer dereference), even though WeaselJsonParser_create can legitimately return nullptr when allocation fails or the requested stack size is too small.

This is the same class of problem that was fixed for WeaselJsonParser_reset and WeaselJsonParser_destroy in #41, but WeaselJsonParser_parse was left out.

Affected code (src/lib.cpp, lines 47-50):

__attribute__((visibility("default"))) WeaselJsonStatus
WeaselJsonParser_parse(WeaselJsonParser *parser, char *buf, int len) {
  return ((Parser3 *)parser)->parse(buf, len);
}

Reproduction:

#include <cstdio>
#include "weaseljson.h"

int main() {
  // WeaselJsonParser_create(1024, nullptr, nullptr, 0) also returns null
  // because callbacks must not be null, but a literal nullptr demonstrates
  // the crash more directly.
  WeaselJsonStatus s = WeaselJsonParser_parse(nullptr, nullptr, 0);
  printf("status: %d\n", s);
  return 0;
}

Compile and run against the shared/static library:

c++ -std=c++20 -I include repro.cpp build/libweaseljson-static.a -o repro
./repro

Actual behavior: segmentation fault (undefined behavior from dereferencing nullptr).

Expected behavior: one of the following, for consistency with the rest of the API:

  1. Return WeaselJson_REJECT immediately (a null parser can never accept input), or
  2. Be a safe no-op like WeaselJsonParser_reset(nullptr) and WeaselJsonParser_destroy(nullptr).

The header already documents that WeaselJsonParser_create may return nullptr, and the existing test reset and destroy accept null parser (src/test.cpp, lines 249-261) confirms that a null parser pointer is a valid state the rest of the API must tolerate. WeaselJsonParser_parse should do the same.

The public C API function `WeaselJsonParser_parse` casts the supplied pointer and dispatches directly without checking for null. Passing `nullptr` causes immediate undefined behavior (a null-pointer dereference), even though `WeaselJsonParser_create` can legitimately return `nullptr` when allocation fails or the requested stack size is too small. This is the same class of problem that was fixed for `WeaselJsonParser_reset` and `WeaselJsonParser_destroy` in #41, but `WeaselJsonParser_parse` was left out. Affected code (`src/lib.cpp`, lines 47-50): ```cpp __attribute__((visibility("default"))) WeaselJsonStatus WeaselJsonParser_parse(WeaselJsonParser *parser, char *buf, int len) { return ((Parser3 *)parser)->parse(buf, len); } ``` Reproduction: ```cpp #include <cstdio> #include "weaseljson.h" int main() { // WeaselJsonParser_create(1024, nullptr, nullptr, 0) also returns null // because callbacks must not be null, but a literal nullptr demonstrates // the crash more directly. WeaselJsonStatus s = WeaselJsonParser_parse(nullptr, nullptr, 0); printf("status: %d\n", s); return 0; } ``` Compile and run against the shared/static library: ```sh c++ -std=c++20 -I include repro.cpp build/libweaseljson-static.a -o repro ./repro ``` Actual behavior: segmentation fault (undefined behavior from dereferencing `nullptr`). Expected behavior: one of the following, for consistency with the rest of the API: 1. Return `WeaselJson_REJECT` immediately (a null parser can never accept input), or 2. Be a safe no-op like `WeaselJsonParser_reset(nullptr)` and `WeaselJsonParser_destroy(nullptr)`. The header already documents that `WeaselJsonParser_create` may return `nullptr`, and the existing test `reset and destroy accept null parser` (`src/test.cpp`, lines 249-261) confirms that a null parser pointer is a valid state the rest of the API must tolerate. `WeaselJsonParser_parse` should do the same.
andrew self-assigned this 2026-07-15 16:35:12 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weaselab/weaseljson#51