This is an automated email from the ASF dual-hosted git repository.

eldenmoon pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/master by this push:
     new d63f8db8648 [fix](json) Replace invalid JSONB with default JSONB null 
value (#59007)
d63f8db8648 is described below

commit d63f8db86486c9c34cbf14fb725dd10b4709107f
Author: Sun Chenyang <[email protected]>
AuthorDate: Mon Dec 15 09:59:38 2025 +0800

    [fix](json) Replace invalid JSONB with default JSONB null value (#59007)
    
    This PR fixes the issue that was supposed to be resolved by
    https://github.com/apache/doris/pull/58656
    . We need to address it as soon as possible, so I am submitting this PR.
---
 be/src/util/jsonb_document.cpp            | 38 +++++++++++++++++++++++++++++++
 be/src/util/jsonb_document.h              | 25 --------------------
 be/test/vec/jsonb/jsonb_document_test.cpp | 15 ++++++++++++
 3 files changed, 53 insertions(+), 25 deletions(-)

diff --git a/be/src/util/jsonb_document.cpp b/be/src/util/jsonb_document.cpp
index 2cebd3f2221..55b12e0e9e6 100644
--- a/be/src/util/jsonb_document.cpp
+++ b/be/src/util/jsonb_document.cpp
@@ -18,12 +18,50 @@
 #include "jsonb_document.h"
 
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "common/status.h"
 #include "util/jsonb_writer.h"
 
 namespace doris {
+
+Status JsonbDocument::checkAndCreateDocument(const char* pb, size_t size,
+                                             const JsonbDocument** doc) {
+    *doc = nullptr;
+    if (!pb || size == 0) {
+        static const std::string buf = []() {
+            JsonbWriter writer;
+            (void)writer.writeNull();
+            auto* out = writer.getOutput();
+            return std::string(out->getBuffer(), out->getSize());
+        }();
+        // Treat empty input as a valid JSONB null document.
+        *doc = reinterpret_cast<const JsonbDocument*>(buf.data());
+        return Status::OK();
+    }
+    if (!pb || size < sizeof(JsonbHeader) + sizeof(JsonbValue)) {
+        return Status::InvalidArgument("Invalid JSONB document: too small 
size({}) or null pointer",
+                                       size);
+    }
+
+    const auto* doc_ptr = (const JsonbDocument*)pb;
+    if (doc_ptr->header_.ver_ != JSONB_VER) {
+        return Status::InvalidArgument("Invalid JSONB document: invalid 
version({})",
+                                       doc_ptr->header_.ver_);
+    }
+
+    const auto* val = (const JsonbValue*)doc_ptr->payload_;
+    if (val->type < JsonbType::T_Null || val->type >= JsonbType::NUM_TYPES ||
+        size != sizeof(JsonbHeader) + val->numPackedBytes()) {
+        return Status::InvalidArgument("Invalid JSONB document: invalid 
type({}) or size({})",
+                                       static_cast<JsonbTypeUnder>(val->type), 
size);
+    }
+
+    *doc = doc_ptr;
+    return Status::OK();
+}
+
 JsonbFindResult JsonbValue::findValue(JsonbPath& path) const {
     JsonbFindResult result;
     bool is_wildcard = false;
diff --git a/be/src/util/jsonb_document.h b/be/src/util/jsonb_document.h
index 9e3bdaed796..0220794a483 100644
--- a/be/src/util/jsonb_document.h
+++ b/be/src/util/jsonb_document.h
@@ -1003,31 +1003,6 @@ struct ArrayVal : public ContainerVal {
     const_iterator end() const { return const_iterator((pointer)(payload + 
size)); }
 };
 
-inline Status JsonbDocument::checkAndCreateDocument(const char* pb, size_t 
size,
-                                                    const JsonbDocument** doc) 
{
-    *doc = nullptr;
-    if (!pb || size < sizeof(JsonbHeader) + sizeof(JsonbValue)) {
-        return Status::InvalidArgument("Invalid JSONB document: too small 
size({}) or null pointer",
-                                       size);
-    }
-
-    const auto* doc_ptr = (const JsonbDocument*)pb;
-    if (doc_ptr->header_.ver_ != JSONB_VER) {
-        return Status::InvalidArgument("Invalid JSONB document: invalid 
version({})",
-                                       doc_ptr->header_.ver_);
-    }
-
-    const auto* val = (const JsonbValue*)doc_ptr->payload_;
-    if (val->type < JsonbType::T_Null || val->type >= JsonbType::NUM_TYPES ||
-        size != sizeof(JsonbHeader) + val->numPackedBytes()) {
-        return Status::InvalidArgument("Invalid JSONB document: invalid 
type({}) or size({})",
-                                       static_cast<JsonbTypeUnder>(val->type), 
size);
-    }
-
-    *doc = doc_ptr;
-    return Status::OK();
-}
-
 inline const JsonbValue* JsonbDocument::createValue(const char* pb, size_t 
size) {
     if (!pb || size < sizeof(JsonbHeader) + sizeof(JsonbValue)) {
         return nullptr;
diff --git a/be/test/vec/jsonb/jsonb_document_test.cpp 
b/be/test/vec/jsonb/jsonb_document_test.cpp
index 56d0f5fa960..e8bd380c883 100644
--- a/be/test/vec/jsonb/jsonb_document_test.cpp
+++ b/be/test/vec/jsonb/jsonb_document_test.cpp
@@ -279,4 +279,19 @@ TEST_F(JsonbDocumentTest, forobject) {
     }
 }
 
+TEST_F(JsonbDocumentTest, invaild_jsonb_document) {
+    const JsonbDocument* doc = nullptr;
+    auto st = JsonbDocument::checkAndCreateDocument(nullptr, 0, &doc);
+    EXPECT_TRUE(st.ok());
+    EXPECT_TRUE(doc != nullptr);
+    EXPECT_TRUE(doc->getValue()->isNull());
+
+    JsonbToJson jsonb_to_json;
+    std::string json_null = jsonb_to_json.to_json_string(doc->getValue());
+    EXPECT_EQ(json_null, "null");
+
+    std::string json_string = JsonbToJson::jsonb_to_json_string(nullptr, 0);
+    EXPECT_EQ(json_null, json_string);
+}
+
 } // namespace doris
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to