[CP] [bugifx] fix json binary read memory out of bound.

This commit is contained in:
obdev
2022-09-16 04:02:30 +00:00
committed by wangzelin.wzl
parent 3daae395f2
commit e3f31ef1ce
2 changed files with 73 additions and 80 deletions

View File

@ -1542,28 +1542,21 @@ int ObJsonBin::get_max_offset(const char* data, ObJsonNodeType cur_node, uint64_
return ret; return ret;
} }
int ObJsonBin::get_use_size(uint64_t& real_size, uint64_t& used_size) const int ObJsonBin::get_use_size(uint64_t &used_size) const
{ {
INIT_SUCC(ret); INIT_SUCC(ret);
int32_t stk_len = stack_size(stack_buf_); int32_t stk_len = stack_size(stack_buf_);
uint8_t node_type, type, obj_size_type; const char *data = curr_.ptr() + pos_;
uint64_t count, obj_size, offset = 0; ObJBVerType ver_type = static_cast<ObJBVerType>(*reinterpret_cast<const uint8_t *>(data));
const char* data = curr_.ptr() + pos_; ObJsonNodeType json_type = static_cast<ObJsonNodeType>(ver_type);
parse_obj_header(data, offset, node_type, type, obj_size_type, count, obj_size);
ObJsonNodeType cur_node = ObJsonVerType::get_json_type(static_cast<ObJBVerType>(node_type));
if (stk_len == 0) { if (stk_len == 0) {
if (!(cur_node == ObJsonNodeType::J_ARRAY || cur_node == ObJsonNodeType::J_OBJECT)) {
real_size = obj_size;
} else {
real_size = curr_.length();
}
used_size = curr_.length(); used_size = curr_.length();
} else { } else {
uint64_t max_offset = 0; uint64_t max_offset = 0;
if (OB_FAIL(get_max_offset(data, cur_node, max_offset))) { if (OB_FAIL(get_max_offset(data, json_type, max_offset))) {
LOG_WARN("get max offset.", K(ret)); LOG_WARN("get max offset.", K(ret));
} else { } else {
real_size = obj_size;
used_size = max_offset; used_size = max_offset;
if (curr_.length() - pos_ < used_size) { if (curr_.length() - pos_ < used_size) {
used_size = curr_.length() - pos_; used_size = curr_.length() - pos_;
@ -1628,14 +1621,14 @@ int ObJsonBin::raw_binary(ObString &buf, ObIAllocator *allocator) const
int ObJsonBin::raw_binary_at_iter(ObString &buf) const int ObJsonBin::raw_binary_at_iter(ObString &buf) const
{ {
INIT_SUCC(ret); INIT_SUCC(ret);
uint64_t used_size = 0, real_size = 0; uint64_t used_size = 0;
if (OB_ISNULL(curr_.ptr())) { if (OB_ISNULL(curr_.ptr())) {
ret = OB_ERR_NULL_VALUE; ret = OB_ERR_NULL_VALUE;
LOG_WARN("json binary ptr is null.", K(ret)); LOG_WARN("json binary ptr is null.", K(ret));
} else if (pos_ >= curr_.length()) { } else if (pos_ >= curr_.length()) {
ret = OB_ERROR_OUT_OF_RANGE; ret = OB_ERROR_OUT_OF_RANGE;
LOG_WARN("json binary iter pos invalid", K(ret), K(pos_), K(curr_.length())); LOG_WARN("json binary iter pos invalid", K(ret), K(pos_), K(curr_.length()));
} else if (OB_FAIL(get_use_size(real_size, used_size))) { } else if (OB_FAIL(get_use_size(used_size))) {
LOG_WARN("get use size failed", K(ret)); LOG_WARN("get use size failed", K(ret));
} else { } else {
buf.assign_ptr(curr_.ptr() + pos_, used_size); buf.assign_ptr(curr_.ptr() + pos_, used_size);

View File

@ -170,8 +170,7 @@ public:
int get_object_value(const ObString &key, ObIJsonBase *&value) const override; int get_object_value(const ObString &key, ObIJsonBase *&value) const override;
int get_key(uint64_t index, common::ObString &key_out) const override; int get_key(uint64_t index, common::ObString &key_out) const override;
int get_raw_binary(common::ObString &out, ObIAllocator *allocator = NULL) const; int get_raw_binary(common::ObString &out, ObIAllocator *allocator = NULL) const;
int get_use_size(uint64_t& obj_size, uint64_t& used_size) const; int get_max_offset(const char *data, ObJsonNodeType cur_node, uint64_t &max_offset) const;
int get_max_offset(const char* data, ObJsonNodeType cur_node, uint64_t& max_offset) const ;
int array_remove(uint64_t index) override; int array_remove(uint64_t index) override;
int object_remove(const common::ObString &key) override; int object_remove(const common::ObString &key) override;
int replace(const ObIJsonBase *old_node, ObIJsonBase *new_node) override; int replace(const ObIJsonBase *old_node, ObIJsonBase *new_node) override;
@ -474,7 +473,8 @@ private:
int check_valid_object_op(uint64_t index) const; int check_valid_object_op(uint64_t index) const;
int check_valid_array_op(uint64_t index) const; int check_valid_array_op(uint64_t index) const;
int create_new_binary(ObIJsonBase *&value, ObJsonBin *&new_bin) const; int create_new_binary(ObIJsonBase *&value, ObJsonBin *&new_bin) const;
/* data */ int get_use_size(uint64_t &used_size) const;
/* data */
private: private:
common::ObIAllocator *allocator_; common::ObIAllocator *allocator_;
ObJsonBuffer result_; ObJsonBuffer result_;