Fix crash on Endpoint params validation

This commit is contained in:
Leonid Stryzhevskyi 2022-09-01 03:22:56 +03:00
parent 2f975359c5
commit e89e4654c4
3 changed files with 39 additions and 61 deletions

View File

@ -71,34 +71,26 @@ const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = __request;
#define OATPP_MACRO_API_CONTROLLER_HEADER_1(TYPE, NAME) \ #define OATPP_MACRO_API_CONTROLLER_HEADER_1(TYPE, NAME) \
const auto& __param_str_val_##NAME = __request->getHeader(#NAME); \ const auto& __param_str_val_##NAME = __request->getHeader(#NAME); \
if(!__param_str_val_##NAME){ \ if(!__param_str_val_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing HEADER parameter '" #NAME "'"); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing HEADER parameter '" #NAME "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} \ } \
bool __param_validation_check_##NAME; \ bool __param_validation_check_##NAME; \
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \ const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
if(!__param_validation_check_##NAME){ \ if(!__param_validation_check_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid HEADER parameter '" #NAME "'. Expected type is '" #TYPE "'"); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid HEADER parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} }
#define OATPP_MACRO_API_CONTROLLER_HEADER_2(TYPE, NAME, QUALIFIER) \ #define OATPP_MACRO_API_CONTROLLER_HEADER_2(TYPE, NAME, QUALIFIER) \
const auto& __param_str_val_##NAME = __request->getHeader(QUALIFIER); \ const auto& __param_str_val_##NAME = __request->getHeader(QUALIFIER); \
if(!__param_str_val_##NAME){ \ if(!__param_str_val_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, oatpp::String("Missing HEADER parameter '") + QUALIFIER + "'"); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, oatpp::String("Missing HEADER parameter '") + QUALIFIER + "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} \ } \
bool __param_validation_check_##NAME; \ bool __param_validation_check_##NAME; \
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \ const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
if(!__param_validation_check_##NAME){ \ if(!__param_validation_check_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, \
oatpp::String("Invalid HEADER parameter '") + \ oatpp::String("Invalid HEADER parameter '") + \
QUALIFIER + \ QUALIFIER + \
"'. Expected type is '" #TYPE "'"); \ "'. Expected type is '" #TYPE "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} }
#define OATPP_MACRO_API_CONTROLLER_HEADER(TYPE, PARAM_LIST) \ #define OATPP_MACRO_API_CONTROLLER_HEADER(TYPE, PARAM_LIST) \
@ -121,35 +113,27 @@ OATPP_MACRO_API_CONTROLLER_MACRO_SELECTOR(OATPP_MACRO_API_CONTROLLER_HEADER_INFO
#define OATPP_MACRO_API_CONTROLLER_PATH_1(TYPE, NAME) \ #define OATPP_MACRO_API_CONTROLLER_PATH_1(TYPE, NAME) \
const auto& __param_str_val_##NAME = __request->getPathVariable(#NAME); \ const auto& __param_str_val_##NAME = __request->getPathVariable(#NAME); \
if(!__param_str_val_##NAME){ \ if(!__param_str_val_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing PATH parameter '" #NAME "'"); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing PATH parameter '" #NAME "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} \ } \
bool __param_validation_check_##NAME; \ bool __param_validation_check_##NAME; \
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \ const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
if(!__param_validation_check_##NAME){ \ if(!__param_validation_check_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid PATH parameter '" #NAME "'. Expected type is '" #TYPE "'"); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid PATH parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} }
#define OATPP_MACRO_API_CONTROLLER_PATH_2(TYPE, NAME, QUALIFIER) \ #define OATPP_MACRO_API_CONTROLLER_PATH_2(TYPE, NAME, QUALIFIER) \
const auto& __param_str_val_##NAME = __request->getPathVariable(QUALIFIER); \ const auto& __param_str_val_##NAME = __request->getPathVariable(QUALIFIER); \
if(!__param_str_val_##NAME){ \ if(!__param_str_val_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, \
oatpp::String("Missing PATH parameter '") + QUALIFIER + "'"); \ oatpp::String("Missing PATH parameter '") + QUALIFIER + "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} \ } \
bool __param_validation_check_##NAME; \ bool __param_validation_check_##NAME; \
const auto NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \ const auto NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
if(!__param_validation_check_##NAME){ \ if(!__param_validation_check_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, \
oatpp::String("Invalid PATH parameter '") + \ oatpp::String("Invalid PATH parameter '") + \
QUALIFIER + \ QUALIFIER + \
"'. Expected type is '" #TYPE "'"); \ "'. Expected type is '" #TYPE "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} }
#define OATPP_MACRO_API_CONTROLLER_PATH(TYPE, PARAM_LIST) \ #define OATPP_MACRO_API_CONTROLLER_PATH(TYPE, PARAM_LIST) \
@ -178,35 +162,27 @@ const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = __request->getQueryParameters();
#define OATPP_MACRO_API_CONTROLLER_QUERY_1(TYPE, NAME) \ #define OATPP_MACRO_API_CONTROLLER_QUERY_1(TYPE, NAME) \
const auto& __param_str_val_##NAME = __request->getQueryParameter(#NAME); \ const auto& __param_str_val_##NAME = __request->getQueryParameter(#NAME); \
if(!__param_str_val_##NAME){ \ if(!__param_str_val_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing QUERY parameter '" #NAME "'"); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing QUERY parameter '" #NAME "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} \ } \
bool __param_validation_check_##NAME; \ bool __param_validation_check_##NAME; \
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \ const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
if(!__param_validation_check_##NAME){ \ if(!__param_validation_check_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid QUERY parameter '" #NAME "'. Expected type is '" #TYPE "'"); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, "Invalid QUERY parameter '" #NAME "'. Expected type is '" #TYPE "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} }
#define OATPP_MACRO_API_CONTROLLER_QUERY_2(TYPE, NAME, QUALIFIER) \ #define OATPP_MACRO_API_CONTROLLER_QUERY_2(TYPE, NAME, QUALIFIER) \
const auto& __param_str_val_##NAME = __request->getQueryParameter(QUALIFIER); \ const auto& __param_str_val_##NAME = __request->getQueryParameter(QUALIFIER); \
if(!__param_str_val_##NAME) \ if(!__param_str_val_##NAME) \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, \
oatpp::String("Missing QUERY parameter '") + QUALIFIER + "'"); \ oatpp::String("Missing QUERY parameter '") + QUALIFIER + "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} \ } \
bool __param_validation_check_##NAME; \ bool __param_validation_check_##NAME; \
const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \ const auto& NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
if(!__param_validation_check_##NAME){ \ if(!__param_validation_check_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, \
oatpp::String("Invalid QUERY parameter '") + \ oatpp::String("Invalid QUERY parameter '") + \
QUALIFIER + \ QUALIFIER + \
"'. Expected type is '" #TYPE "'"); \ "'. Expected type is '" #TYPE "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} }
#define OATPP_MACRO_API_CONTROLLER_QUERY_3(TYPE, NAME, QUALIFIER, DEFAULT) \ #define OATPP_MACRO_API_CONTROLLER_QUERY_3(TYPE, NAME, QUALIFIER, DEFAULT) \
@ -216,12 +192,10 @@ if(__param_str_val_##NAME) { \
bool __param_validation_check_##NAME; \ bool __param_validation_check_##NAME; \
NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \ NAME = ApiController::TypeInterpretation<TYPE>::fromString(#TYPE, __param_str_val_##NAME, __param_validation_check_##NAME); \
if(!__param_validation_check_##NAME){ \ if(!__param_validation_check_##NAME){ \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, \
oatpp::String("Invalid QUERY parameter '") + \ oatpp::String("Invalid QUERY parameter '") + \
QUALIFIER + \ QUALIFIER + \
"'. Expected type is '" #TYPE "'"); \ "'. Expected type is '" #TYPE "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} \ } \
} }
@ -261,16 +235,12 @@ if(getDefaultObjectMapper()) { \
#define OATPP_MACRO_API_CONTROLLER_BODY_DTO(TYPE, PARAM_LIST) \ #define OATPP_MACRO_API_CONTROLLER_BODY_DTO(TYPE, PARAM_LIST) \
if(!getDefaultObjectMapper()) { \ if(!getDefaultObjectMapper()) { \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_500, "ObjectMapper was NOT set. Can't deserialize the request body."); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_500, "ObjectMapper was NOT set. Can't deserialize the request body."); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} \ } \
const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = \ const auto& OATPP_MACRO_FIRSTARG PARAM_LIST = \
__request->readBodyToDto<TYPE>(getDefaultObjectMapper().get()); \ __request->readBodyToDto<TYPE>(getDefaultObjectMapper().get()); \
if(!OATPP_MACRO_FIRSTARG PARAM_LIST) { \ if(!OATPP_MACRO_FIRSTARG PARAM_LIST) { \
auto httpError = oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing valid body parameter '" OATPP_MACRO_FIRSTARG_STR PARAM_LIST "'"); \ throw oatpp::web::protocol::http::HttpError(Status::CODE_400, "Missing valid body parameter '" OATPP_MACRO_FIRSTARG_STR PARAM_LIST "'"); \
auto eptr = std::make_exception_ptr(httpError); \
return ApiController::handleError(eptr); \
} }
// __INFO // __INFO

View File

@ -56,11 +56,17 @@ void ApiController::setErrorHandler(const std::shared_ptr<handler::ErrorHandler>
} }
std::shared_ptr<ApiController::OutgoingResponse> ApiController::handleError(const std::exception_ptr& exceptionPtr) const { std::shared_ptr<ApiController::OutgoingResponse> ApiController::handleError(const std::exception_ptr& exceptionPtr) const {
if(m_errorHandler) { if(m_errorHandler) {
return m_errorHandler->handleError(exceptionPtr); return m_errorHandler->handleError(exceptionPtr);
} }
return nullptr; if(exceptionPtr) {
std::rethrow_exception(exceptionPtr);
}
throw std::runtime_error("[oatpp::web::server::api::ApiController::handleError()]: Error. 'exceptionPtr' is not set.");
} }
void ApiController::setDefaultAuthorizationHandler(const std::shared_ptr<handler::AuthorizationHandler>& authorizationHandler){ void ApiController::setDefaultAuthorizationHandler(const std::shared_ptr<handler::AuthorizationHandler>& authorizationHandler){

View File

@ -360,7 +360,9 @@ public:
ApiController(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& defaultObjectMapper, const oatpp::String &routerPrefix = nullptr) ApiController(const std::shared_ptr<oatpp::data::mapping::ObjectMapper>& defaultObjectMapper, const oatpp::String &routerPrefix = nullptr)
: m_defaultObjectMapper(defaultObjectMapper) : m_defaultObjectMapper(defaultObjectMapper)
, m_routerPrefix(routerPrefix) , m_routerPrefix(routerPrefix)
{} {
}
public: public:
template<class T> template<class T>