ps protocol analysis add defense check
This commit is contained in:
@ -63,6 +63,19 @@ using namespace sql;
|
|||||||
using namespace pl;
|
using namespace pl;
|
||||||
namespace observer
|
namespace observer
|
||||||
{
|
{
|
||||||
|
inline int ObPSAnalysisChecker::detection(const int64_t len)
|
||||||
|
{
|
||||||
|
int ret = OB_SUCCESS;
|
||||||
|
if (!need_check_) {
|
||||||
|
} else if (*pos_ + len > end_pos_) {
|
||||||
|
ret = OB_ERR_MALFORMED_PS_PACKET;
|
||||||
|
LOG_USER_ERROR(OB_ERR_MALFORMED_PS_PACKET);
|
||||||
|
LOG_ERROR("malformed ps data packet, please check the number and content of data packet parameters", K(ret), KP(pos_), KP(begin_pos_),
|
||||||
|
K(end_pos_ - begin_pos_), K(len), K(data_len_), K(remain_len()));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ObMPStmtExecute::ObMPStmtExecute(const ObGlobalContext &gctx)
|
ObMPStmtExecute::ObMPStmtExecute(const ObGlobalContext &gctx)
|
||||||
: ObMPBase(gctx),
|
: ObMPBase(gctx),
|
||||||
retry_ctrl_(/*ctx_.retry_info_*/),
|
retry_ctrl_(/*ctx_.retry_info_*/),
|
||||||
@ -506,7 +519,12 @@ int ObMPStmtExecute::before_process()
|
|||||||
}
|
}
|
||||||
const ObMySQLRawPacket &pkt = reinterpret_cast<const ObMySQLRawPacket&>(req_->get_packet());
|
const ObMySQLRawPacket &pkt = reinterpret_cast<const ObMySQLRawPacket&>(req_->get_packet());
|
||||||
const char* pos = pkt.get_cdata();
|
const char* pos = pkt.get_cdata();
|
||||||
|
analysis_checker_.init(pos, pkt.get_clen());
|
||||||
int32_t stmt_id = -1; //INVALID_STMT_ID
|
int32_t stmt_id = -1; //INVALID_STMT_ID
|
||||||
|
uint32_t ps_stmt_checksum = 0;
|
||||||
|
ObSQLSessionInfo *session = NULL;
|
||||||
|
PS_DEFENSE_CHECK(9) // stmt_id(4) + flag(1) + checksum(4)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int4(pos, stmt_id);
|
ObMySQLUtil::get_int4(pos, stmt_id);
|
||||||
stmt_id_ = stmt_id;
|
stmt_id_ = stmt_id;
|
||||||
|
|
||||||
@ -522,13 +540,12 @@ int ObMPStmtExecute::before_process()
|
|||||||
: ObNormalType;
|
: ObNormalType;
|
||||||
|
|
||||||
// 4 bytes, iteration-count, used for checksum
|
// 4 bytes, iteration-count, used for checksum
|
||||||
uint32_t ps_stmt_checksum = 0;
|
|
||||||
ObMySQLUtil::get_uint4(pos, ps_stmt_checksum);
|
ObMySQLUtil::get_uint4(pos, ps_stmt_checksum);
|
||||||
|
|
||||||
ObSQLSessionInfo *session = NULL;
|
|
||||||
if (is_arraybinding_) {
|
if (is_arraybinding_) {
|
||||||
OZ (init_for_arraybinding(alloc));
|
OZ (init_for_arraybinding(alloc));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
} else if (OB_FAIL(get_session(session))) {
|
} else if (OB_FAIL(get_session(session))) {
|
||||||
LOG_WARN("get session failed");
|
LOG_WARN("get session failed");
|
||||||
@ -611,11 +628,14 @@ int ObMPStmtExecute::parse_request_type(const char* &pos,
|
|||||||
uint8_t type = 0;
|
uint8_t type = 0;
|
||||||
int8_t flag = 0;
|
int8_t flag = 0;
|
||||||
if (1 == new_param_bound_flag) {
|
if (1 == new_param_bound_flag) {
|
||||||
|
PS_DEFENSE_CHECK(2) // type(1) + flag(1)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_uint1(pos, type);
|
ObMySQLUtil::get_uint1(pos, type);
|
||||||
ObMySQLUtil::get_int1(pos, flag);
|
ObMySQLUtil::get_int1(pos, flag);
|
||||||
if (OB_FAIL(param_types.push_back(static_cast<EMySQLFieldType>(type)))) {
|
if (OB_FAIL(param_types.push_back(static_cast<EMySQLFieldType>(type)))) {
|
||||||
LOG_WARN("fail to push back", K(type), K(i));
|
LOG_WARN("fail to push back", K(type), K(i));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (num_of_params != param_types.count()) {
|
if (num_of_params != param_types.count()) {
|
||||||
ret = OB_ERR_WRONG_DYNAMIC_PARAM;
|
ret = OB_ERR_WRONG_DYNAMIC_PARAM;
|
||||||
@ -634,9 +654,12 @@ int ObMPStmtExecute::parse_request_type(const char* &pos,
|
|||||||
if (OB_FAIL(decode_type_info(pos, type_name_info))) {
|
if (OB_FAIL(decode_type_info(pos, type_name_info))) {
|
||||||
LOG_WARN("failed to decode type info", K(ret));
|
LOG_WARN("failed to decode type info", K(ret));
|
||||||
} else if (type_name_info.type_name_.empty()) {
|
} else if (type_name_info.type_name_.empty()) {
|
||||||
type_name_info.is_elem_type_ = true;
|
|
||||||
ObMySQLUtil::get_uint1(pos, elem_type);
|
|
||||||
ObObjType ob_elem_type;
|
ObObjType ob_elem_type;
|
||||||
|
type_name_info.is_elem_type_ = true;
|
||||||
|
PS_DEFENSE_CHECK(1) // elem_type(1)
|
||||||
|
{
|
||||||
|
ObMySQLUtil::get_uint1(pos, elem_type);
|
||||||
|
}
|
||||||
OZ (ObSMUtils::get_ob_type(
|
OZ (ObSMUtils::get_ob_type(
|
||||||
ob_elem_type, static_cast<EMySQLFieldType>(elem_type)), elem_type);
|
ob_elem_type, static_cast<EMySQLFieldType>(elem_type)), elem_type);
|
||||||
OX (type_name_info.elem_type_.set_obj_type(ob_elem_type));
|
OX (type_name_info.elem_type_.set_obj_type(ob_elem_type));
|
||||||
@ -718,6 +741,19 @@ int ObMPStmtExecute::parse_request_param_value(ObIAllocator &alloc,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ObMPStmtExecute::is_contain_complex_element(const sql::ParamTypeArray ¶m_types) const
|
||||||
|
{
|
||||||
|
bool b_ret = false;
|
||||||
|
for (int64_t i = 0; i < param_types.count(); i++) {
|
||||||
|
const obmysql::EMySQLFieldType field_type = param_types.at(i);
|
||||||
|
if (MYSQL_TYPE_COMPLEX == field_type) {
|
||||||
|
b_ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b_ret;
|
||||||
|
}
|
||||||
|
|
||||||
int ObMPStmtExecute::request_params(ObSQLSessionInfo *session,
|
int ObMPStmtExecute::request_params(ObSQLSessionInfo *session,
|
||||||
const char* &pos,
|
const char* &pos,
|
||||||
uint32_t ps_stmt_checksum,
|
uint32_t ps_stmt_checksum,
|
||||||
@ -793,18 +829,21 @@ int ObMPStmtExecute::request_params(ObSQLSessionInfo *session,
|
|||||||
int64_t bitmap_types = (params_num_ + 7) / 8;
|
int64_t bitmap_types = (params_num_ + 7) / 8;
|
||||||
const char *bitmap = pos;
|
const char *bitmap = pos;
|
||||||
pos += bitmap_types;
|
pos += bitmap_types;
|
||||||
// Step2: 获取new_param_bound_flag字段
|
|
||||||
ObMySQLUtil::get_int1(pos, new_param_bound_flag);
|
|
||||||
ParamTypeArray ¶m_types = ps_session_info->get_param_types();
|
ParamTypeArray ¶m_types = ps_session_info->get_param_types();
|
||||||
ParamTypeInfoArray param_type_infos;
|
ParamTypeInfoArray param_type_infos;
|
||||||
ParamCastArray param_cast_infos;
|
ParamCastArray param_cast_infos;
|
||||||
|
|
||||||
ParamTypeArray returning_param_types;
|
ParamTypeArray returning_param_types;
|
||||||
ParamTypeInfoArray returning_param_type_infos;
|
ParamTypeInfoArray returning_param_type_infos;
|
||||||
|
int64_t len = bitmap_types + 1/*new_param_bound_flag*/;
|
||||||
|
PS_DEFENSE_CHECK(len) // bitmap_types
|
||||||
|
{
|
||||||
|
// Step2: 获取new_param_bound_flag字段
|
||||||
|
ObMySQLUtil::get_int1(pos, new_param_bound_flag);
|
||||||
if (new_param_bound_flag == 1) {
|
if (new_param_bound_flag == 1) {
|
||||||
param_types.reuse();
|
param_types.reuse();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else if (OB_FAIL(param_type_infos.prepare_allocate(input_param_num))) {
|
} else if (OB_FAIL(param_type_infos.prepare_allocate(input_param_num))) {
|
||||||
@ -839,6 +878,8 @@ int ObMPStmtExecute::request_params(ObSQLSessionInfo *session,
|
|||||||
param_types,
|
param_types,
|
||||||
param_type_infos))) {
|
param_type_infos))) {
|
||||||
LOG_WARN("fail to parse input params type", K(ret));
|
LOG_WARN("fail to parse input params type", K(ret));
|
||||||
|
} else if (is_contain_complex_element(param_types)) {
|
||||||
|
analysis_checker_.need_check_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step3-2: 获取returning into params type信息
|
// Step3-2: 获取returning into params type信息
|
||||||
@ -920,19 +961,25 @@ int ObMPStmtExecute::decode_type_info(const char*& buf, TypeInfo &type_info)
|
|||||||
if (OB_FAIL(ObMySQLUtil::get_length(buf, length))) {
|
if (OB_FAIL(ObMySQLUtil::get_length(buf, length))) {
|
||||||
LOG_WARN("failed to get length", K(ret));
|
LOG_WARN("failed to get length", K(ret));
|
||||||
} else {
|
} else {
|
||||||
|
PS_DEFENSE_CHECK(length)
|
||||||
|
{
|
||||||
type_info.relation_name_.assign_ptr(buf, static_cast<ObString::obstr_size_t>(length));
|
type_info.relation_name_.assign_ptr(buf, static_cast<ObString::obstr_size_t>(length));
|
||||||
buf += length;
|
buf += length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
uint64_t length = 0;
|
uint64_t length = 0;
|
||||||
if (OB_FAIL(ObMySQLUtil::get_length(buf, length))) {
|
if (OB_FAIL(ObMySQLUtil::get_length(buf, length))) {
|
||||||
LOG_WARN("failed to get length", K(ret));
|
LOG_WARN("failed to get length", K(ret));
|
||||||
} else {
|
} else {
|
||||||
|
PS_DEFENSE_CHECK(length)
|
||||||
|
{
|
||||||
type_info.type_name_.assign_ptr(buf, static_cast<ObString::obstr_size_t>(length));
|
type_info.type_name_.assign_ptr(buf, static_cast<ObString::obstr_size_t>(length));
|
||||||
buf += length;
|
buf += length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
uint64_t version = 0;
|
uint64_t version = 0;
|
||||||
if (OB_FAIL(ObMySQLUtil::get_length(buf, version))) {
|
if (OB_FAIL(ObMySQLUtil::get_length(buf, version))) {
|
||||||
@ -2000,7 +2047,8 @@ int ObMPStmtExecute::parse_basic_param_value(ObIAllocator &allocator,
|
|||||||
const char *& data,
|
const char *& data,
|
||||||
const common::ObTimeZoneInfo *tz_info,
|
const common::ObTimeZoneInfo *tz_info,
|
||||||
ObObj ¶m,
|
ObObj ¶m,
|
||||||
bool is_complex_element)
|
bool is_complex_element,
|
||||||
|
ObPSAnalysisChecker *checker)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
UNUSED(charset);
|
UNUSED(charset);
|
||||||
@ -2009,27 +2057,35 @@ int ObMPStmtExecute::parse_basic_param_value(ObIAllocator &allocator,
|
|||||||
case MYSQL_TYPE_SHORT:
|
case MYSQL_TYPE_SHORT:
|
||||||
case MYSQL_TYPE_LONG:
|
case MYSQL_TYPE_LONG:
|
||||||
case MYSQL_TYPE_LONGLONG: {
|
case MYSQL_TYPE_LONGLONG: {
|
||||||
if (OB_FAIL(parse_integer_value(type, data, param, allocator, is_complex_element))) {
|
if (OB_FAIL(parse_integer_value(type, data, param, allocator, is_complex_element, checker))) {
|
||||||
LOG_WARN("parse integer value from client failed", K(ret));
|
LOG_WARN("parse integer value from client failed", K(ret));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_FLOAT: {
|
case MYSQL_TYPE_FLOAT: {
|
||||||
float value = 0;
|
float value = 0;
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, sizeof(value))
|
||||||
|
{
|
||||||
MEMCPY(&value, data, sizeof(value));
|
MEMCPY(&value, data, sizeof(value));
|
||||||
data += sizeof(value);
|
data += sizeof(value);
|
||||||
param.set_float(value);
|
param.set_float(value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_ORA_BINARY_FLOAT: {
|
case MYSQL_TYPE_ORA_BINARY_FLOAT: {
|
||||||
float value = 0;
|
float value = 0;
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, sizeof(value))
|
||||||
|
{
|
||||||
MEMCPY(&value, data, sizeof(value));
|
MEMCPY(&value, data, sizeof(value));
|
||||||
data += sizeof(value);
|
data += sizeof(value);
|
||||||
param.set_float(value);
|
param.set_float(value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_DOUBLE: {
|
case MYSQL_TYPE_DOUBLE: {
|
||||||
double value = 0;
|
double value = 0;
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, sizeof(value))
|
||||||
|
{
|
||||||
MEMCPY(&value, data, sizeof(value));
|
MEMCPY(&value, data, sizeof(value));
|
||||||
data += sizeof(value);
|
data += sizeof(value);
|
||||||
if (lib::is_mysql_mode()) {
|
if (lib::is_mysql_mode()) {
|
||||||
@ -2051,32 +2107,39 @@ int ObMPStmtExecute::parse_basic_param_value(ObIAllocator &allocator,
|
|||||||
param.set_number(nb);
|
param.set_number(nb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_ORA_BINARY_DOUBLE: {
|
case MYSQL_TYPE_ORA_BINARY_DOUBLE: {
|
||||||
double value = 0;
|
double value = 0;
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, sizeof(value))
|
||||||
|
{
|
||||||
MEMCPY(&value, data, sizeof(value));
|
MEMCPY(&value, data, sizeof(value));
|
||||||
data += sizeof(value);
|
data += sizeof(value);
|
||||||
param.set_double(value);
|
param.set_double(value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_YEAR: {
|
case MYSQL_TYPE_YEAR: {
|
||||||
int16_t value = 0;
|
int16_t value = 0;
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 2)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int2(data, value);
|
ObMySQLUtil::get_int2(data, value);
|
||||||
param.set_year(static_cast<uint8_t>(value));
|
param.set_year(static_cast<uint8_t>(value));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_DATE:
|
case MYSQL_TYPE_DATE:
|
||||||
case MYSQL_TYPE_DATETIME:
|
case MYSQL_TYPE_DATETIME:
|
||||||
case MYSQL_TYPE_TIMESTAMP: {
|
case MYSQL_TYPE_TIMESTAMP: {
|
||||||
if (OB_FAIL(parse_mysql_timestamp_value(static_cast<EMySQLFieldType>(type), data,
|
if (OB_FAIL(parse_mysql_timestamp_value(static_cast<EMySQLFieldType>(type), data,
|
||||||
param, tz_info))) {
|
param, tz_info, checker))) {
|
||||||
LOG_WARN("parse timestamp value from client failed", K(ret));
|
LOG_WARN("parse timestamp value from client failed", K(ret));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_TIME:{
|
case MYSQL_TYPE_TIME:{
|
||||||
if (OB_FAIL(parse_mysql_time_value(data, param))) {
|
if (OB_FAIL(parse_mysql_time_value(data, param, checker))) {
|
||||||
LOG_WARN("parse timestamp value from client failed", K(ret));
|
LOG_WARN("parse timestamp value from client failed", K(ret));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2086,7 +2149,7 @@ int ObMPStmtExecute::parse_basic_param_value(ObIAllocator &allocator,
|
|||||||
case MYSQL_TYPE_OB_TIMESTAMP_NANO: {
|
case MYSQL_TYPE_OB_TIMESTAMP_NANO: {
|
||||||
ObTimeConvertCtx cvrt_ctx(tz_info, true);
|
ObTimeConvertCtx cvrt_ctx(tz_info, true);
|
||||||
if (OB_FAIL(parse_oracle_timestamp_value(
|
if (OB_FAIL(parse_oracle_timestamp_value(
|
||||||
static_cast<EMySQLFieldType>(type), data, cvrt_ctx, param))) {
|
static_cast<EMySQLFieldType>(type), data, cvrt_ctx, param, checker))) {
|
||||||
LOG_WARN("parse timestamp value from client failed", K(ret));
|
LOG_WARN("parse timestamp value from client failed", K(ret));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2115,7 +2178,10 @@ int ObMPStmtExecute::parse_basic_param_value(ObIAllocator &allocator,
|
|||||||
if (OB_FAIL(ObMySQLUtil::get_length(data, length))) {
|
if (OB_FAIL(ObMySQLUtil::get_length(data, length))) {
|
||||||
LOG_ERROR("decode varchar param value failed", K(ret));
|
LOG_ERROR("decode varchar param value failed", K(ret));
|
||||||
} else {
|
} else {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, length)
|
||||||
|
{
|
||||||
str.assign_ptr(data, static_cast<ObString::obstr_size_t>(length));
|
str.assign_ptr(data, static_cast<ObString::obstr_size_t>(length));
|
||||||
|
}
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
} else if (MYSQL_TYPE_OB_NVARCHAR2 == type
|
} else if (MYSQL_TYPE_OB_NVARCHAR2 == type
|
||||||
|| MYSQL_TYPE_OB_NCHAR == type) {
|
|| MYSQL_TYPE_OB_NCHAR == type) {
|
||||||
@ -2291,13 +2357,13 @@ int ObMPStmtExecute::parse_basic_param_value(ObIAllocator &allocator,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_OB_INTERVAL_YM: {
|
case MYSQL_TYPE_OB_INTERVAL_YM: {
|
||||||
if (OB_FAIL(parse_oracle_interval_ym_value(data, param))) {
|
if (OB_FAIL(parse_oracle_interval_ym_value(data, param, checker))) {
|
||||||
LOG_WARN("failed to parse oracle interval year to month value", K(ret));
|
LOG_WARN("failed to parse oracle interval year to month value", K(ret));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_OB_INTERVAL_DS:{
|
case MYSQL_TYPE_OB_INTERVAL_DS:{
|
||||||
if (OB_FAIL(parse_oracle_interval_ds_value(data, param))) {
|
if (OB_FAIL(parse_oracle_interval_ds_value(data, param, checker))) {
|
||||||
LOG_WARN("failed to parse oracle interval year to month value", K(ret));
|
LOG_WARN("failed to parse oracle interval year to month value", K(ret));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2356,7 +2422,7 @@ int ObMPStmtExecute::parse_param_value(ObIAllocator &allocator,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (OB_FAIL(parse_basic_param_value(allocator, type, charset, cs_type, ncs_type,
|
if (OB_FAIL(parse_basic_param_value(allocator, type, charset, cs_type, ncs_type,
|
||||||
data, tz_info, param))) {
|
data, tz_info, param, false, &analysis_checker_))) {
|
||||||
LOG_WARN("failed to parse basic param value", K(ret));
|
LOG_WARN("failed to parse basic param value", K(ret));
|
||||||
} else {
|
} else {
|
||||||
param.set_param_meta();
|
param.set_param_meta();
|
||||||
@ -2440,7 +2506,7 @@ int ObMPStmtExecute::parse_param_value(ObIAllocator &allocator,
|
|||||||
} else {
|
} else {
|
||||||
const char* src = tmp;
|
const char* src = tmp;
|
||||||
if (OB_FAIL(parse_basic_param_value(allocator, type, charset, cs_type, ncs_type,
|
if (OB_FAIL(parse_basic_param_value(allocator, type, charset, cs_type, ncs_type,
|
||||||
src, tz_info, param))) {
|
src, tz_info, param, false))) {
|
||||||
LOG_WARN("failed to parse basic param value", K(ret));
|
LOG_WARN("failed to parse basic param value", K(ret));
|
||||||
} else {
|
} else {
|
||||||
param.set_param_meta();
|
param.set_param_meta();
|
||||||
@ -2515,19 +2581,25 @@ int ObMPStmtExecute::parse_integer_value(const uint32_t type,
|
|||||||
const char *&data,
|
const char *&data,
|
||||||
ObObj ¶m,
|
ObObj ¶m,
|
||||||
ObIAllocator &allocator,
|
ObIAllocator &allocator,
|
||||||
bool is_complex_element)
|
bool is_complex_element,
|
||||||
|
ObPSAnalysisChecker *checker)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
bool cast_to_number = !(lib::is_mysql_mode() || is_complex_element || MYSQL_TYPE_TINY == type);
|
bool cast_to_number = !(lib::is_mysql_mode() || is_complex_element || MYSQL_TYPE_TINY == type);
|
||||||
int64_t res_val = 0;
|
int64_t res_val = 0;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case MYSQL_TYPE_TINY: {
|
case MYSQL_TYPE_TINY: {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 1)
|
||||||
|
{
|
||||||
int8_t value;
|
int8_t value;
|
||||||
ObMySQLUtil::get_int1(data, value);
|
ObMySQLUtil::get_int1(data, value);
|
||||||
param.set_tinyint(value);
|
param.set_tinyint(value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_SHORT: {
|
case MYSQL_TYPE_SHORT: {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 2)
|
||||||
|
{
|
||||||
int16_t value = 0;
|
int16_t value = 0;
|
||||||
ObMySQLUtil::get_int2(data, value);
|
ObMySQLUtil::get_int2(data, value);
|
||||||
if (!cast_to_number) {
|
if (!cast_to_number) {
|
||||||
@ -2535,9 +2607,12 @@ int ObMPStmtExecute::parse_integer_value(const uint32_t type,
|
|||||||
} else {
|
} else {
|
||||||
res_val = static_cast<int64_t>(value);
|
res_val = static_cast<int64_t>(value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_LONG: {
|
case MYSQL_TYPE_LONG: {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 4)
|
||||||
|
{
|
||||||
int32_t value = 0;
|
int32_t value = 0;
|
||||||
ObMySQLUtil::get_int4(data, value);
|
ObMySQLUtil::get_int4(data, value);
|
||||||
if (!cast_to_number) {
|
if (!cast_to_number) {
|
||||||
@ -2545,9 +2620,12 @@ int ObMPStmtExecute::parse_integer_value(const uint32_t type,
|
|||||||
} else {
|
} else {
|
||||||
res_val = static_cast<int64_t>(value);
|
res_val = static_cast<int64_t>(value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MYSQL_TYPE_LONGLONG: {
|
case MYSQL_TYPE_LONGLONG: {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 8)
|
||||||
|
{
|
||||||
int64_t value = 0;
|
int64_t value = 0;
|
||||||
ObMySQLUtil::get_int8(data, value);
|
ObMySQLUtil::get_int8(data, value);
|
||||||
if (!cast_to_number) {
|
if (!cast_to_number) {
|
||||||
@ -2555,6 +2633,7 @@ int ObMPStmtExecute::parse_integer_value(const uint32_t type,
|
|||||||
} else {
|
} else {
|
||||||
res_val = value;
|
res_val = value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@ -2577,7 +2656,8 @@ int ObMPStmtExecute::parse_integer_value(const uint32_t type,
|
|||||||
int ObMPStmtExecute::parse_mysql_timestamp_value(const EMySQLFieldType field_type,
|
int ObMPStmtExecute::parse_mysql_timestamp_value(const EMySQLFieldType field_type,
|
||||||
const char *&data,
|
const char *&data,
|
||||||
ObObj ¶m,
|
ObObj ¶m,
|
||||||
const common::ObTimeZoneInfo *tz_info)
|
const common::ObTimeZoneInfo *tz_info,
|
||||||
|
ObPSAnalysisChecker *checker)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
int8_t length = 0;
|
int8_t length = 0;
|
||||||
@ -2588,22 +2668,32 @@ int ObMPStmtExecute::parse_mysql_timestamp_value(const EMySQLFieldType field_typ
|
|||||||
int8_t min = 0;
|
int8_t min = 0;
|
||||||
int8_t second = 0;
|
int8_t second = 0;
|
||||||
int32_t microsecond = 0;
|
int32_t microsecond = 0;
|
||||||
ObMySQLUtil::get_int1(data, length);
|
|
||||||
ObPreciseDateTime value;
|
ObPreciseDateTime value;
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 1)
|
||||||
|
{
|
||||||
|
ObMySQLUtil::get_int1(data, length);
|
||||||
if (0 == length) {
|
if (0 == length) {
|
||||||
value = 0;
|
value = 0;
|
||||||
} else if (4 == length) {
|
} else if (4 == length) {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 4)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int2(data, year);
|
ObMySQLUtil::get_int2(data, year);
|
||||||
ObMySQLUtil::get_int1(data, month);
|
ObMySQLUtil::get_int1(data, month);
|
||||||
ObMySQLUtil::get_int1(data, day);
|
ObMySQLUtil::get_int1(data, day);
|
||||||
|
}
|
||||||
} else if (7 == length) {
|
} else if (7 == length) {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 7)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int2(data, year);
|
ObMySQLUtil::get_int2(data, year);
|
||||||
ObMySQLUtil::get_int1(data, month);
|
ObMySQLUtil::get_int1(data, month);
|
||||||
ObMySQLUtil::get_int1(data, day);
|
ObMySQLUtil::get_int1(data, day);
|
||||||
ObMySQLUtil::get_int1(data, hour);
|
ObMySQLUtil::get_int1(data, hour);
|
||||||
ObMySQLUtil::get_int1(data, min);
|
ObMySQLUtil::get_int1(data, min);
|
||||||
ObMySQLUtil::get_int1(data, second);
|
ObMySQLUtil::get_int1(data, second);
|
||||||
|
}
|
||||||
} else if (11 == length) {
|
} else if (11 == length) {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 11)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int2(data, year);
|
ObMySQLUtil::get_int2(data, year);
|
||||||
ObMySQLUtil::get_int1(data, month);
|
ObMySQLUtil::get_int1(data, month);
|
||||||
ObMySQLUtil::get_int1(data, day);
|
ObMySQLUtil::get_int1(data, day);
|
||||||
@ -2611,10 +2701,12 @@ int ObMPStmtExecute::parse_mysql_timestamp_value(const EMySQLFieldType field_typ
|
|||||||
ObMySQLUtil::get_int1(data, min);
|
ObMySQLUtil::get_int1(data, min);
|
||||||
ObMySQLUtil::get_int1(data, second);
|
ObMySQLUtil::get_int1(data, second);
|
||||||
ObMySQLUtil::get_int4(data, microsecond);
|
ObMySQLUtil::get_int4(data, microsecond);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = OB_ERROR;
|
ret = OB_ERROR;
|
||||||
LOG_WARN("invalid mysql timestamp value length", K(length));
|
LOG_WARN("invalid mysql timestamp value length", K(length));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
ObTime ob_time;
|
ObTime ob_time;
|
||||||
@ -2665,27 +2757,34 @@ int ObMPStmtExecute::parse_mysql_timestamp_value(const EMySQLFieldType field_typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ObMPStmtExecute::parse_oracle_timestamp_value(const obmysql::EMySQLFieldType field_type,
|
int ObMPStmtExecute::parse_oracle_timestamp_value(const obmysql::EMySQLFieldType field_type,
|
||||||
const char *&data, const ObTimeConvertCtx &cvrt_ctx, ObObj ¶m)
|
const char *&data, const ObTimeConvertCtx &cvrt_ctx, ObObj ¶m, ObPSAnalysisChecker *checker)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
int8_t total_len = 0;
|
int8_t total_len = 0;
|
||||||
ObObjType obj_type;
|
ObObjType obj_type;
|
||||||
ObOTimestampData ot_data;
|
ObOTimestampData ot_data;
|
||||||
int8_t scale = -1;
|
int8_t scale = -1;
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 1)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int1(data, total_len);
|
ObMySQLUtil::get_int1(data, total_len);
|
||||||
if (OB_FAIL(ObSMUtils::get_ob_type(obj_type, field_type))) {
|
}
|
||||||
|
if (OB_FAIL(ret)) {
|
||||||
|
} else if (OB_FAIL(ObSMUtils::get_ob_type(obj_type, field_type))) {
|
||||||
LOG_WARN("failed to get_ob_type", K(ret));
|
LOG_WARN("failed to get_ob_type", K(ret));
|
||||||
} else if (OB_FAIL(ObTimeConverter::decode_otimestamp(obj_type, data, total_len, cvrt_ctx, ot_data, scale))) {
|
} else if (OB_FAIL(ObTimeConverter::decode_otimestamp(obj_type, data, total_len, cvrt_ctx, ot_data, scale))) {
|
||||||
LOG_WARN("failed to decode_otimestamp", K(ret));
|
LOG_WARN("failed to decode_otimestamp", K(ret));
|
||||||
} else {
|
} else {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, total_len)
|
||||||
|
{
|
||||||
data += total_len;
|
data += total_len;
|
||||||
param.set_otimestamp_value(obj_type, ot_data);
|
param.set_otimestamp_value(obj_type, ot_data);
|
||||||
param.set_scale(scale);
|
param.set_scale(scale);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObMPStmtExecute::parse_mysql_time_value(const char *&data, ObObj ¶m)
|
int ObMPStmtExecute::parse_mysql_time_value(const char *&data, ObObj ¶m, ObPSAnalysisChecker *checker)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
int8_t length = 0;
|
int8_t length = 0;
|
||||||
@ -2699,23 +2798,31 @@ int ObMPStmtExecute::parse_mysql_time_value(const char *&data, ObObj ¶m)
|
|||||||
int32_t microsecond = 0;
|
int32_t microsecond = 0;
|
||||||
struct tm tmval;
|
struct tm tmval;
|
||||||
MEMSET(&tmval, 0, sizeof(tmval));
|
MEMSET(&tmval, 0, sizeof(tmval));
|
||||||
ObMySQLUtil::get_int1(data, length);
|
|
||||||
int64_t value;
|
int64_t value;
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 1)
|
||||||
|
{
|
||||||
|
ObMySQLUtil::get_int1(data, length);
|
||||||
if (0 == length) {
|
if (0 == length) {
|
||||||
value = 0;
|
value = 0;
|
||||||
} else if (8 == length) {
|
} else if (8 == length) {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 8)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int1(data, is_negative);
|
ObMySQLUtil::get_int1(data, is_negative);
|
||||||
ObMySQLUtil::get_int4(data, day);
|
ObMySQLUtil::get_int4(data, day);
|
||||||
ObMySQLUtil::get_int1(data, hour);
|
ObMySQLUtil::get_int1(data, hour);
|
||||||
ObMySQLUtil::get_int1(data, min);
|
ObMySQLUtil::get_int1(data, min);
|
||||||
ObMySQLUtil::get_int1(data, second);
|
ObMySQLUtil::get_int1(data, second);
|
||||||
|
}
|
||||||
} else if (12 == length) {
|
} else if (12 == length) {
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, 12)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int1(data, is_negative);
|
ObMySQLUtil::get_int1(data, is_negative);
|
||||||
ObMySQLUtil::get_int4(data, day);
|
ObMySQLUtil::get_int4(data, day);
|
||||||
ObMySQLUtil::get_int1(data, hour);
|
ObMySQLUtil::get_int1(data, hour);
|
||||||
ObMySQLUtil::get_int1(data, min);
|
ObMySQLUtil::get_int1(data, min);
|
||||||
ObMySQLUtil::get_int1(data, second);
|
ObMySQLUtil::get_int1(data, second);
|
||||||
ObMySQLUtil::get_int4(data, microsecond);
|
ObMySQLUtil::get_int4(data, microsecond);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
LOG_ERROR("unexpected time length", K(length), K(ret));
|
LOG_ERROR("unexpected time length", K(length), K(ret));
|
||||||
@ -2740,6 +2847,7 @@ int ObMPStmtExecute::parse_mysql_time_value(const char *&data, ObObj ¶m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
param.set_time(value);
|
param.set_time(value);
|
||||||
}
|
}
|
||||||
@ -2747,7 +2855,7 @@ int ObMPStmtExecute::parse_mysql_time_value(const char *&data, ObObj ¶m)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObMPStmtExecute::parse_oracle_interval_ds_value(const char *&data, ObObj ¶m)
|
int ObMPStmtExecute::parse_oracle_interval_ds_value(const char *&data, ObObj ¶m, ObPSAnalysisChecker *checker)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
int8_t length = 0;
|
int8_t length = 0;
|
||||||
@ -2755,18 +2863,20 @@ int ObMPStmtExecute::parse_oracle_interval_ds_value(const char *&data, ObObj &pa
|
|||||||
ObIntervalDSValue value;
|
ObIntervalDSValue value;
|
||||||
|
|
||||||
ObMySQLUtil::get_int1(data, length);
|
ObMySQLUtil::get_int1(data, length);
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, length)
|
||||||
|
{
|
||||||
if (OB_FAIL(ObTimeConverter::decode_interval_ds(data, length, value, scale))) {
|
if (OB_FAIL(ObTimeConverter::decode_interval_ds(data, length, value, scale))) {
|
||||||
LOG_WARN("fail to decode interval day to second", K(ret), K(length));
|
LOG_WARN("fail to decode interval day to second", K(ret), K(length));
|
||||||
} else {
|
} else {
|
||||||
param.set_interval_ds(value);
|
param.set_interval_ds(value);
|
||||||
param.set_scale(scale);
|
param.set_scale(scale);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ObMPStmtExecute::parse_oracle_interval_ym_value(const char *&data, ObObj ¶m)
|
int ObMPStmtExecute::parse_oracle_interval_ym_value(const char *&data, ObObj ¶m, ObPSAnalysisChecker *checker)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
int8_t length = 0;
|
int8_t length = 0;
|
||||||
@ -2774,12 +2884,15 @@ int ObMPStmtExecute::parse_oracle_interval_ym_value(const char *&data, ObObj &pa
|
|||||||
ObIntervalYMValue value;
|
ObIntervalYMValue value;
|
||||||
|
|
||||||
ObMySQLUtil::get_int1(data, length);
|
ObMySQLUtil::get_int1(data, length);
|
||||||
|
PS_STATIC_DEFENSE_CHECK(checker, length)
|
||||||
|
{
|
||||||
if (OB_FAIL(ObTimeConverter::decode_interval_ym(data, length, value, scale))) {
|
if (OB_FAIL(ObTimeConverter::decode_interval_ym(data, length, value, scale))) {
|
||||||
LOG_WARN("fail to decode interval year to month", K(ret), K(length));
|
LOG_WARN("fail to decode interval year to month", K(ret), K(length));
|
||||||
} else {
|
} else {
|
||||||
param.set_interval_ym(value);
|
param.set_interval_ym(value);
|
||||||
param.set_scale(scale);
|
param.set_scale(scale);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,46 @@ enum ObPSCursorType
|
|||||||
ObPrexecutePsCursorType
|
ObPrexecutePsCursorType
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ObPSAnalysisChecker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ObPSAnalysisChecker()
|
||||||
|
: pos_(nullptr), begin_pos_(nullptr), end_pos_(nullptr),
|
||||||
|
data_len_(0), need_check_(true)
|
||||||
|
{}
|
||||||
|
void init(const char*& pos, const int64_t len)
|
||||||
|
{
|
||||||
|
pos_ = &pos;
|
||||||
|
begin_pos_ = pos;
|
||||||
|
end_pos_ = pos + len;
|
||||||
|
data_len_ = len;
|
||||||
|
need_check_ = true;
|
||||||
|
}
|
||||||
|
int detection(const int64_t len);
|
||||||
|
inline int64_t remain_len()
|
||||||
|
{ return end_pos_ - (*pos_); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
const char** pos_;
|
||||||
|
const char* begin_pos_;
|
||||||
|
const char* end_pos_;
|
||||||
|
int64_t data_len_;
|
||||||
|
bool need_check_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define PS_DEFENSE_CHECK(len) \
|
||||||
|
if (OB_FAIL(ret)) { \
|
||||||
|
} else if (OB_FAIL(analysis_checker_.detection(len))) { \
|
||||||
|
LOG_WARN("memory access out of bounds", K(ret)); \
|
||||||
|
} else
|
||||||
|
|
||||||
|
#define PS_STATIC_DEFENSE_CHECK(checker, len) \
|
||||||
|
if (OB_FAIL(ret)) { \
|
||||||
|
} else if (nullptr != checker \
|
||||||
|
&& OB_FAIL(checker->detection(len))) { \
|
||||||
|
LOG_WARN("memory access out of bounds", K(ret)); \
|
||||||
|
} else
|
||||||
|
|
||||||
class ObMPStmtExecute : public ObMPBase
|
class ObMPStmtExecute : public ObMPBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -62,21 +102,25 @@ public:
|
|||||||
const char *& data,
|
const char *& data,
|
||||||
const common::ObTimeZoneInfo *tz_info,
|
const common::ObTimeZoneInfo *tz_info,
|
||||||
ObObj ¶m,
|
ObObj ¶m,
|
||||||
bool is_complex_element = false);
|
bool is_complex_element = false,
|
||||||
|
ObPSAnalysisChecker *checker = nullptr);
|
||||||
static int parse_mysql_timestamp_value(const obmysql::EMySQLFieldType field_type,
|
static int parse_mysql_timestamp_value(const obmysql::EMySQLFieldType field_type,
|
||||||
const char *&data,
|
const char *&data,
|
||||||
ObObj ¶m,
|
ObObj ¶m,
|
||||||
const common::ObTimeZoneInfo *tz_info);
|
const common::ObTimeZoneInfo *tz_info,
|
||||||
|
ObPSAnalysisChecker *checker = nullptr);
|
||||||
static int parse_integer_value(const uint32_t type,
|
static int parse_integer_value(const uint32_t type,
|
||||||
const char *&data,
|
const char *&data,
|
||||||
ObObj ¶m,
|
ObObj ¶m,
|
||||||
ObIAllocator &allocator,
|
ObIAllocator &allocator,
|
||||||
bool is_complex_element = false);
|
bool is_complex_element = false,
|
||||||
|
ObPSAnalysisChecker *checker = nullptr);
|
||||||
static int parse_oracle_timestamp_value(const obmysql::EMySQLFieldType field_type, const char *&data,
|
static int parse_oracle_timestamp_value(const obmysql::EMySQLFieldType field_type, const char *&data,
|
||||||
const ObTimeConvertCtx &cvrt_ctx, ObObj ¶m);
|
const ObTimeConvertCtx &cvrt_ctx, ObObj ¶m,
|
||||||
static int parse_mysql_time_value(const char *&data, ObObj ¶m);
|
ObPSAnalysisChecker *checker = nullptr);
|
||||||
static int parse_oracle_interval_ym_value(const char *&data, ObObj ¶m);
|
static int parse_mysql_time_value(const char *&data, ObObj ¶m, ObPSAnalysisChecker *checker = nullptr);
|
||||||
static int parse_oracle_interval_ds_value(const char *&data, ObObj ¶m);
|
static int parse_oracle_interval_ym_value(const char *&data, ObObj ¶m, ObPSAnalysisChecker *checker = nullptr);
|
||||||
|
static int parse_oracle_interval_ds_value(const char *&data, ObObj ¶m, ObPSAnalysisChecker *checker = nullptr);
|
||||||
int64_t get_single_process_timestamp() const { return single_process_timestamp_; }
|
int64_t get_single_process_timestamp() const { return single_process_timestamp_; }
|
||||||
int64_t get_exec_start_timestamp() const { return exec_start_timestamp_; }
|
int64_t get_exec_start_timestamp() const { return exec_start_timestamp_; }
|
||||||
int64_t get_exec_end_timestamp() const { return exec_end_timestamp_; }
|
int64_t get_exec_end_timestamp() const { return exec_end_timestamp_; }
|
||||||
@ -275,6 +319,7 @@ private:
|
|||||||
int get_pl_type_by_type_info(ObIAllocator &allocator,
|
int get_pl_type_by_type_info(ObIAllocator &allocator,
|
||||||
const sql::TypeInfo *type_info,
|
const sql::TypeInfo *type_info,
|
||||||
const pl::ObUserDefinedType *&pl_type);
|
const pl::ObUserDefinedType *&pl_type);
|
||||||
|
bool is_contain_complex_element(const sql::ParamTypeArray ¶m_types) const;
|
||||||
|
|
||||||
virtual int before_process();
|
virtual int before_process();
|
||||||
int response_query_header(sql::ObSQLSessionInfo &session, pl::ObDbmsCursorInfo &cursor);
|
int response_query_header(sql::ObSQLSessionInfo &session, pl::ObDbmsCursorInfo &cursor);
|
||||||
@ -314,6 +359,7 @@ protected:
|
|||||||
int64_t params_value_len_;
|
int64_t params_value_len_;
|
||||||
char *params_value_;
|
char *params_value_;
|
||||||
int64_t curr_sql_idx_; // only for arraybinding
|
int64_t curr_sql_idx_; // only for arraybinding
|
||||||
|
ObPSAnalysisChecker analysis_checker_;
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(ObMPStmtExecute);
|
DISALLOW_COPY_AND_ASSIGN(ObMPStmtExecute);
|
||||||
|
|
||||||
|
|||||||
@ -102,8 +102,11 @@ int ObMPStmtPrexecute::before_process()
|
|||||||
}
|
}
|
||||||
const ObMySQLRawPacket &pkt = reinterpret_cast<const ObMySQLRawPacket&>(req_->get_packet());
|
const ObMySQLRawPacket &pkt = reinterpret_cast<const ObMySQLRawPacket&>(req_->get_packet());
|
||||||
const char* pos = pkt.get_cdata();
|
const char* pos = pkt.get_cdata();
|
||||||
|
analysis_checker_.init(pos, pkt.get_clen());
|
||||||
// stmt_id
|
// stmt_id
|
||||||
int32_t stmt_id = -1;
|
int32_t stmt_id = -1;
|
||||||
|
PS_DEFENSE_CHECK(9) // stmt_id(4) + flag(1) + iteration_count(4)
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int4(pos, stmt_id);
|
ObMySQLUtil::get_int4(pos, stmt_id);
|
||||||
stmt_id_ = stmt_id;
|
stmt_id_ = stmt_id;
|
||||||
|
|
||||||
@ -113,22 +116,28 @@ int ObMPStmtPrexecute::before_process()
|
|||||||
|
|
||||||
// iteration_count
|
// iteration_count
|
||||||
ObMySQLUtil::get_int4(pos, iteration_count_);
|
ObMySQLUtil::get_int4(pos, iteration_count_);
|
||||||
|
}
|
||||||
|
|
||||||
// sql
|
// sql
|
||||||
if (OB_SUCC(ret) && OB_FAIL(ObMySQLUtil::get_length(pos, sql_len_))) {
|
if (OB_SUCC(ret) && OB_FAIL(ObMySQLUtil::get_length(pos, sql_len_))) {
|
||||||
LOG_WARN("failed to get length", K(ret));
|
LOG_WARN("failed to get length", K(ret));
|
||||||
} else {
|
} else {
|
||||||
|
PS_DEFENSE_CHECK(sql_len_)
|
||||||
|
{
|
||||||
sql_.assign_ptr(pos, static_cast<ObString::obstr_size_t>(sql_len_));
|
sql_.assign_ptr(pos, static_cast<ObString::obstr_size_t>(sql_len_));
|
||||||
pos += sql_len_;
|
pos += sql_len_;
|
||||||
|
}
|
||||||
LOG_DEBUG("get sql in prexecute protocol.", K(stmt_id_), K(sql_));
|
LOG_DEBUG("get sql in prexecute protocol.", K(stmt_id_), K(sql_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// params_num
|
// params_num
|
||||||
int32_t num = 0;
|
int32_t num = 0;
|
||||||
|
ObSQLSessionInfo *session = NULL;
|
||||||
|
PS_DEFENSE_CHECK(4) // params_num
|
||||||
|
{
|
||||||
ObMySQLUtil::get_int4(pos, num);
|
ObMySQLUtil::get_int4(pos, num);
|
||||||
set_param_num(num);
|
set_param_num(num);
|
||||||
|
}
|
||||||
ObSQLSessionInfo *session = NULL;
|
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else if (OB_FAIL(get_session(session))) {
|
} else if (OB_FAIL(get_session(session))) {
|
||||||
@ -284,6 +293,8 @@ int ObMPStmtPrexecute::before_process()
|
|||||||
if (OB_FAIL(request_params(session, pos, ps_stmt_checksum, *allocator_, params_num_))) {
|
if (OB_FAIL(request_params(session, pos, ps_stmt_checksum, *allocator_, params_num_))) {
|
||||||
LOG_WARN("prepare-execute protocol get params request failed", K(ret));
|
LOG_WARN("prepare-execute protocol get params request failed", K(ret));
|
||||||
} else {
|
} else {
|
||||||
|
PS_DEFENSE_CHECK(4) // exec_mode
|
||||||
|
{
|
||||||
ObMySQLUtil::get_uint4(pos, exec_mode_);
|
ObMySQLUtil::get_uint4(pos, exec_mode_);
|
||||||
//
|
//
|
||||||
// is_commit_on_success_ is not use yet
|
// is_commit_on_success_ is not use yet
|
||||||
@ -293,7 +304,10 @@ int ObMPStmtPrexecute::before_process()
|
|||||||
if (OB_OCI_BATCH_ERRORS == exec_mode_ && !is_pl_stmt(stmt_type_)) {
|
if (OB_OCI_BATCH_ERRORS == exec_mode_ && !is_pl_stmt(stmt_type_)) {
|
||||||
set_save_exception(true);
|
set_save_exception(true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
|
PS_DEFENSE_CHECK(4) // close stmt count
|
||||||
|
{
|
||||||
ObMySQLUtil::get_uint4(pos, close_stmt_count_);
|
ObMySQLUtil::get_uint4(pos, close_stmt_count_);
|
||||||
int tmp_ret = OB_SUCCESS;
|
int tmp_ret = OB_SUCCESS;
|
||||||
if (0 != close_stmt_count_) {
|
if (0 != close_stmt_count_) {
|
||||||
@ -317,7 +331,10 @@ int ObMPStmtPrexecute::before_process()
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
|
PS_DEFENSE_CHECK(4) // checksum
|
||||||
|
{
|
||||||
ObMySQLUtil::get_uint4(pos, ps_stmt_checksum);
|
ObMySQLUtil::get_uint4(pos, ps_stmt_checksum);
|
||||||
if (DEFAULT_ITERATION_COUNT == ps_stmt_checksum
|
if (DEFAULT_ITERATION_COUNT == ps_stmt_checksum
|
||||||
|| (OB_NOT_NULL(ps_session_info)
|
|| (OB_NOT_NULL(ps_session_info)
|
||||||
@ -326,9 +343,13 @@ int ObMPStmtPrexecute::before_process()
|
|||||||
LOG_ERROR("ps stmt checksum fail", K(ret), "session_id", session->get_sessid(),
|
LOG_ERROR("ps stmt checksum fail", K(ret), "session_id", session->get_sessid(),
|
||||||
K(ps_stmt_checksum), K(*ps_session_info));
|
K(ps_stmt_checksum), K(*ps_session_info));
|
||||||
} else {
|
} else {
|
||||||
|
PS_DEFENSE_CHECK(4) // extend_flag
|
||||||
|
{
|
||||||
ObMySQLUtil::get_uint4(pos, extend_flag_);
|
ObMySQLUtil::get_uint4(pos, extend_flag_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (OB_FAIL(ret)) {
|
if (OB_FAIL(ret)) {
|
||||||
// do nothing
|
// do nothing
|
||||||
} else if (is_send_long_data()) {
|
} else if (is_send_long_data()) {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -2238,6 +2238,7 @@ DEFINE_ERROR_EXT(OB_ERR_SP_NO_DROP_SP, -9743, ER_SP_NO_DROP_SP, "HY000", "Can't
|
|||||||
DEFINE_ORACLE_ERROR(OB_ERR_RECOMPILATION_OBJECT, -9744, -1, "HY000", "errors during recompilation/revalidation of object", 4045, "errors during recompilation/revalidation of %.*s.%.*s");
|
DEFINE_ORACLE_ERROR(OB_ERR_RECOMPILATION_OBJECT, -9744, -1, "HY000", "errors during recompilation/revalidation of object", 4045, "errors during recompilation/revalidation of %.*s.%.*s");
|
||||||
DEFINE_ORACLE_ERROR(OB_ERR_VARIABLE_NOT_IN_SELECT_LIST, -9745, -1, "HY000", "variable not in select list", 1007, "variable not in select list");
|
DEFINE_ORACLE_ERROR(OB_ERR_VARIABLE_NOT_IN_SELECT_LIST, -9745, -1, "HY000", "variable not in select list", 1007, "variable not in select list");
|
||||||
DEFINE_ORACLE_ERROR(OB_ERR_MULTI_RECORD, -9746, -1, "HY000", "coercion into multiple record targets not supported", 494, "coercion into multiple record targets not supported");
|
DEFINE_ORACLE_ERROR(OB_ERR_MULTI_RECORD, -9746, -1, "HY000", "coercion into multiple record targets not supported", 494, "coercion into multiple record targets not supported");
|
||||||
|
DEFINE_ERROR(OB_ERR_MALFORMED_PS_PACKET, -9747, -1, "HY000", "malformed ps packet");
|
||||||
////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////
|
||||||
// !!! text/blob || clob/blob erro code
|
// !!! text/blob || clob/blob erro code
|
||||||
// for compat we cant not remove this errno!!!!
|
// for compat we cant not remove this errno!!!!
|
||||||
|
|||||||
@ -1698,6 +1698,7 @@ constexpr int OB_ERR_SP_NO_DROP_SP = -9743;
|
|||||||
constexpr int OB_ERR_RECOMPILATION_OBJECT = -9744;
|
constexpr int OB_ERR_RECOMPILATION_OBJECT = -9744;
|
||||||
constexpr int OB_ERR_VARIABLE_NOT_IN_SELECT_LIST = -9745;
|
constexpr int OB_ERR_VARIABLE_NOT_IN_SELECT_LIST = -9745;
|
||||||
constexpr int OB_ERR_MULTI_RECORD = -9746;
|
constexpr int OB_ERR_MULTI_RECORD = -9746;
|
||||||
|
constexpr int OB_ERR_MALFORMED_PS_PACKET = -9747;
|
||||||
constexpr int OB_SP_RAISE_APPLICATION_ERROR = -20000;
|
constexpr int OB_SP_RAISE_APPLICATION_ERROR = -20000;
|
||||||
constexpr int OB_SP_RAISE_APPLICATION_ERROR_NUM = -21000;
|
constexpr int OB_SP_RAISE_APPLICATION_ERROR_NUM = -21000;
|
||||||
constexpr int OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN = -22998;
|
constexpr int OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN = -22998;
|
||||||
@ -3739,6 +3740,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
|
|||||||
#define OB_ERR_RECOMPILATION_OBJECT__USER_ERROR_MSG "errors during recompilation/revalidation of object"
|
#define OB_ERR_RECOMPILATION_OBJECT__USER_ERROR_MSG "errors during recompilation/revalidation of object"
|
||||||
#define OB_ERR_VARIABLE_NOT_IN_SELECT_LIST__USER_ERROR_MSG "variable not in select list"
|
#define OB_ERR_VARIABLE_NOT_IN_SELECT_LIST__USER_ERROR_MSG "variable not in select list"
|
||||||
#define OB_ERR_MULTI_RECORD__USER_ERROR_MSG "coercion into multiple record targets not supported"
|
#define OB_ERR_MULTI_RECORD__USER_ERROR_MSG "coercion into multiple record targets not supported"
|
||||||
|
#define OB_ERR_MALFORMED_PS_PACKET__USER_ERROR_MSG "malformed ps packet"
|
||||||
#define OB_SP_RAISE_APPLICATION_ERROR__USER_ERROR_MSG "%.*s"
|
#define OB_SP_RAISE_APPLICATION_ERROR__USER_ERROR_MSG "%.*s"
|
||||||
#define OB_SP_RAISE_APPLICATION_ERROR_NUM__USER_ERROR_MSG "error number argument to raise_application_error of '%d' is out of range"
|
#define OB_SP_RAISE_APPLICATION_ERROR_NUM__USER_ERROR_MSG "error number argument to raise_application_error of '%d' is out of range"
|
||||||
#define OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN__USER_ERROR_MSG "CLOB or NCLOB in multibyte character set not supported"
|
#define OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN__USER_ERROR_MSG "CLOB or NCLOB in multibyte character set not supported"
|
||||||
@ -5780,6 +5782,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
|
|||||||
#define OB_ERR_RECOMPILATION_OBJECT__ORA_USER_ERROR_MSG "ORA-04045: errors during recompilation/revalidation of %.*s.%.*s"
|
#define OB_ERR_RECOMPILATION_OBJECT__ORA_USER_ERROR_MSG "ORA-04045: errors during recompilation/revalidation of %.*s.%.*s"
|
||||||
#define OB_ERR_VARIABLE_NOT_IN_SELECT_LIST__ORA_USER_ERROR_MSG "ORA-01007: variable not in select list"
|
#define OB_ERR_VARIABLE_NOT_IN_SELECT_LIST__ORA_USER_ERROR_MSG "ORA-01007: variable not in select list"
|
||||||
#define OB_ERR_MULTI_RECORD__ORA_USER_ERROR_MSG "ORA-00494: coercion into multiple record targets not supported"
|
#define OB_ERR_MULTI_RECORD__ORA_USER_ERROR_MSG "ORA-00494: coercion into multiple record targets not supported"
|
||||||
|
#define OB_ERR_MALFORMED_PS_PACKET__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -9747, malformed ps packet"
|
||||||
#define OB_SP_RAISE_APPLICATION_ERROR__ORA_USER_ERROR_MSG "ORA%06ld: %.*s"
|
#define OB_SP_RAISE_APPLICATION_ERROR__ORA_USER_ERROR_MSG "ORA%06ld: %.*s"
|
||||||
#define OB_SP_RAISE_APPLICATION_ERROR_NUM__ORA_USER_ERROR_MSG "ORA-21000: error number argument to raise_application_error of '%d' is out of range"
|
#define OB_SP_RAISE_APPLICATION_ERROR_NUM__ORA_USER_ERROR_MSG "ORA-21000: error number argument to raise_application_error of '%d' is out of range"
|
||||||
#define OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN__ORA_USER_ERROR_MSG "ORA-22998: CLOB or NCLOB in multibyte character set not supported"
|
#define OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN__ORA_USER_ERROR_MSG "ORA-22998: CLOB or NCLOB in multibyte character set not supported"
|
||||||
@ -5790,7 +5793,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
|
|||||||
#define OB_ERR_DATA_TOO_LONG_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-12899: value too large for column %.*s (actual: %ld, maximum: %ld)"
|
#define OB_ERR_DATA_TOO_LONG_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-12899: value too large for column %.*s (actual: %ld, maximum: %ld)"
|
||||||
#define OB_ERR_INVALID_DATE_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-01861: Incorrect datetime value for column '%.*s' at row %ld"
|
#define OB_ERR_INVALID_DATE_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-01861: Incorrect datetime value for column '%.*s' at row %ld"
|
||||||
|
|
||||||
extern int g_all_ob_errnos[2037];
|
extern int g_all_ob_errnos[2038];
|
||||||
|
|
||||||
const char *ob_error_name(const int oberr);
|
const char *ob_error_name(const int oberr);
|
||||||
const char* ob_error_cause(const int oberr);
|
const char* ob_error_cause(const int oberr);
|
||||||
|
|||||||
Reference in New Issue
Block a user