N1QL query with 'undefined' property in args crashes node.js process
Description
Environment
Gerrit Reviews
Release Notes Description
Activity
Jared Casey November 3, 2022 at 6:42 PM
Fixed crash – named and positional params can now handle undefined params.
Sergey Auseyau November 2, 2022 at 7:20 PM
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
undefined, Function, and Symbol values are not valid JSON values. If any such values are encountered during conversion, they are either omitted (when found in an object) or changed to null (when found in an array). JSON.stringify() can return undefined when passing in "pure" values like JSON.stringify(() => {}) or JSON.stringify(undefined).
Sergey Auseyau November 2, 2022 at 7:11 PM
Ah, I see the possible problem:
> JSON.stringify(undefined)
undefined
> JSON.stringify(null)
'null'
Does it have something to do with encoding primitives?
Sergey Auseyau November 2, 2022 at 7:09 PM
> JSON.stringify({'foo': 42, 'baz': null, 'bar': undefined})
'{"foo":42,"baz":null}'
> JSON.stringify(['foo', 42, undefined, null, undefined])
'["foo",42,null,null,null]'
Could it be something different? my node.js generates strange, but valid JSON.
Sergey Auseyau November 2, 2022 at 7:06 PM
we can raise exception if positional parameters contain `undefined`, because encoding that would be undefined behaviour 🙂
I have a project using node.js that uses the CB SDK to make N1QL queries. Recently queries have started to crash the node.js process, with an uncaught C++ exception. I attached LLDB to get a backtrace, and it appears to be Couchbase code responsible.
libc++abi: terminating with uncaught exception of type tao::pegtl::parse_error: tao::json::events::from_string:1:1: no valid JSON Process 72959 stopped * thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT frame #0: 0x00007ff80256e00e libsystem_kernel.dylib`__pthread_kill + 10 libsystem_kernel.dylib`: -> 0x7ff80256e00e <+10>: jae 0x7ff80256e018 ; <+20> 0x7ff80256e010 <+12>: movq %rax, %rdi 0x7ff80256e013 <+15>: jmp 0x7ff8025681c5 ; cerror_nocancel 0x7ff80256e018 <+20>: retq Target 0: (node) stopped. (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT * frame #0: 0x00007ff80256e00e libsystem_kernel.dylib`__pthread_kill + 10 frame #1: 0x00007ff8025a41ff libsystem_pthread.dylib`pthread_kill + 263 frame #2: 0x00007ff8024efd24 libsystem_c.dylib`abort + 123 frame #3: 0x00007ff802560082 libc++abi.dylib`abort_message + 241 frame #4: 0x00007ff8025511a5 libc++abi.dylib`demangling_terminate_handler() + 242 frame #5: 0x00007ff80244de19 libobjc.A.dylib`_objc_terminate() + 104 frame #6: 0x00007ff80255f4a7 libc++abi.dylib`std::__terminate(void (*)()) + 8 frame #7: 0x00007ff80255f458 libc++abi.dylib`std::terminate() + 56 frame #8: 0x0000000112129d3b couchbase_impl.node`__clang_call_terminate + 11 frame #9: 0x0000000112137e28 couchbase_impl.node`napi_value__* Napi::details::TemplatedInstanceCallback<couchnode::Connection, &(couchnode::Connection::jsQuery(Napi::CallbackInfo const&))>(napi_env__*, napi_callback_info__*) + 328 frame #10: 0x00000001001eb3f3 node`v8impl::(anonymous namespace)::FunctionCallbackWrapper::Invoke(v8::FunctionCallbackInfo<v8::Value> const&) + 109 frame #11: 0x00000001003e42bf node`v8::internal::FunctionCallbackArguments::Call(v8::internal::CallHandlerInfo) + 217 frame #12: 0x00000001003e40a5 node`v8::internal::MaybeHandle<v8::internal::Object> v8::internal::(anonymous namespace)::HandleApiCallHelper<false>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::HeapObject>, v8::internal::Handle<v8::internal::FunctionTemplateInfo>, v8::internal::Handle<v8::internal::Object>, v8::internal::BuiltinArguments) + 529 frame #13: 0x00000001003e3b2d node`v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) + 256