Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions be/src/util/jsonb_document.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
25 changes: 0 additions & 25 deletions be/src/util/jsonb_document.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
15 changes: 15 additions & 0 deletions be/test/vec/jsonb/jsonb_document_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading