[CP] Fix core caused by out-of-bounds access to the question mark name array

This commit is contained in:
obdev
2022-07-04 10:11:30 +08:00
committed by wangzelin.wzl
parent fa70d54091
commit 669b4d93af
3 changed files with 40 additions and 14 deletions

View File

@ -567,19 +567,41 @@ int64_t get_question_mark(ObQuestionMarkCtx* ctx, void* malloc_pool, const char*
if (OB_UNLIKELY(NULL == ctx || NULL == name)) { if (OB_UNLIKELY(NULL == ctx || NULL == name)) {
(void)fprintf(stderr, "ERROR question mark ctx or name is NULL\n"); (void)fprintf(stderr, "ERROR question mark ctx or name is NULL\n");
} else { } else {
bool valid_name = true; if (NULL == ctx->name_ && 0 == ctx->capacity_) {
for (int64_t i = 0; valid_name && -1 == idx && i < ctx->count_; ++i) { ctx->capacity_ = MAX_QUESTION_MARK;
if (NULL == ctx->name_[i]) { // the errocde will be ignored here. TO BE FIXED.
(void)fprintf(stderr, "ERROR name_ in question mark ctx is null\n"); ctx->name_ = (char **)parse_malloc(sizeof(char*) * MAX_QUESTION_MARK, malloc_pool);
valid_name = false;
} else if (0 == STRCASECMP(ctx->name_[i], name)) {
idx = i;
}
} }
if (-1 == idx && valid_name) { if (ctx->name_ != NULL) {
int64_t len = 0; bool valid_name = true;
ctx->name_[ctx->count_] = parse_strdup(name, malloc_pool, &len); for (int64_t i = 0; valid_name && -1 == idx && i < ctx->count_; ++i) {
idx = ctx->count_++; if (NULL == ctx->name_[i]) {
(void)fprintf(stderr, "ERROR name_ in question mark ctx is null\n");
valid_name = false;
} else if (0 == STRCASECMP(ctx->name_[i], name)) {
idx = i;
}
}
if (-1 == idx && valid_name) {
if (ctx->count_ >= ctx->capacity_) {
void *buf = parse_malloc(sizeof(char*) * (ctx->capacity_ * 2), malloc_pool);
if (OB_UNLIKELY(NULL == buf)) {
ctx->name_ = NULL;
(void)printf("ERROR malloc memory failed\n");
} else {
MEMCPY(buf, ctx->name_, sizeof(char*) * ctx->capacity_);
ctx->capacity_ *= 2;
ctx->name_ = (char **)buf;
}
}
if (ctx->name_ != NULL) {
int64_t len = 0;
ctx->name_[ctx->count_] = parse_strdup(name, malloc_pool, &len);
idx = ctx->count_++;
}
}
} else {
(void)fprintf(stderr, "ERROR question mark name buffer is null\n");
} }
} }
return idx; return idx;

View File

@ -178,9 +178,11 @@ typedef struct _PLParseInfo {
#define MAX_QUESTION_MARK 128 #define MAX_QUESTION_MARK 128
typedef struct _ObQuestionMarkCtx { typedef struct _ObQuestionMarkCtx
char* name_[MAX_QUESTION_MARK]; {
char **name_;
int count_; int count_;
int capacity_;
bool by_ordinal_; bool by_ordinal_;
bool by_name_; bool by_name_;
} ObQuestionMarkCtx; } ObQuestionMarkCtx;

View File

@ -64,6 +64,8 @@ int parse_reset(ParseResult* p)
p->question_mark_ctx_.count_ = 0; p->question_mark_ctx_.count_ = 0;
p->question_mark_ctx_.by_ordinal_ = false; p->question_mark_ctx_.by_ordinal_ = false;
p->question_mark_ctx_.by_name_ = false; p->question_mark_ctx_.by_name_ = false;
p->question_mark_ctx_.name_ = NULL;
p->question_mark_ctx_.capacity_ = 0;
p->sql_mode_ = 0; p->sql_mode_ = 0;
p->has_encount_comment_ = false; p->has_encount_comment_ = false;