From d33798d495d50df427dac0dc6934220e366976fb Mon Sep 17 00:00:00 2001 From: John Bartholomew Date: Fri, 13 Mar 2026 14:22:42 +0000 Subject: [PATCH] fix: null pointer deref in FRAME_BUILTIN_FORCE_THUNKS impl Since https://github.com/google/jsonnet/pull/1299 there is a code-path which constructs a `FRAME_BUILTIN_FORCE_THUNKS` Frame with `nullptr` `ast`. Somehow this did not cause crashes in the test suite (until it was run with a more hardened build) --- core/vm.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/vm.cpp b/core/vm.cpp index 0f4ec2a3..c243496c 100644 --- a/core/vm.cpp +++ b/core/vm.cpp @@ -2798,11 +2798,11 @@ class Interpreter { } break; case FRAME_BUILTIN_FORCE_THUNKS: { - const auto &ast = *static_cast(f.ast); + const auto &location = f.location; auto *func = static_cast(f.val.v.h); if (f.elementId == f.thunks.size()) { // All thunks forced, now the builtin implementations. - const LocationRange &loc = ast.location; + const LocationRange &loc = location; const std::string &builtin_name = func->builtinName; std::vector args; for (const auto &p : func->params) { @@ -2855,7 +2855,7 @@ class Interpreter { break; default: - throw makeError(ast.location, + throw makeError(location, "native extensions can only take primitives."); } } @@ -2864,7 +2864,7 @@ class Interpreter { args3.push_back(&args2[i]); } if (nit == nativeCallbacks.end()) { - throw makeError(ast.location, + throw makeError(location, "unrecognized builtin name: " + builtin_name); } const VmNativeCallback &cb = nit->second; @@ -2878,18 +2878,18 @@ class Interpreter { } else { if (r->kind != JsonnetJsonValue::STRING) { throw makeError( - ast.location, + location, "native extension returned an error that was not a string."); } std::string rs = r->string; - throw makeError(ast.location, rs); + throw makeError(location, rs); } } else { // Not all arguments forced yet. HeapThunk *th = f.thunks[f.elementId++]; if (!th->filled) { - stack.newCall(ast.location, th, th->self, th->offset, th->upValues); + stack.newCall(location, th, th->self, th->offset, th->upValues); ast_ = th->body; goto recurse; } else {