diff options
author | JackLivio <jack@livio.io> | 2019-03-13 13:08:03 -0400 |
---|---|---|
committer | JackLivio <jack@livio.io> | 2019-03-13 13:08:03 -0400 |
commit | 265c8ae2b94bf4d4a5daf667667aabcdf873de5f (patch) | |
tree | 23fd9eaa09b1e3fa2841b5345f003e9908542ad8 | |
parent | 1c32db10769c284450346b5e2de829bb437bff7e (diff) | |
parent | f29db0b23aac8295f5712c0a30086dcad5bf5199 (diff) | |
download | sdl_core-265c8ae2b94bf4d4a5daf667667aabcdf873de5f.tar.gz |
Merge branch 'develop' of github.com:smartdevicelink/sdl_core into tests/cloud_app_disconnect
28 files changed, 227 insertions, 91 deletions
diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h index 90af5afebf..8668f10d2c 100644 --- a/src/components/application_manager/include/application_manager/application_manager_impl.h +++ b/src/components/application_manager/include/application_manager/application_manager_impl.h @@ -1149,7 +1149,7 @@ class ApplicationManagerImpl bool ConvertSOtoMessage(const smart_objects::SmartObject& message, Message& output, - const bool remove_unknown_parameters = true); + const bool allow_unknown_parameters = false); template <typename ApplicationList> void PrepareApplicationListSO(ApplicationList app_list, diff --git a/src/components/application_manager/include/application_manager/rpc_handler_impl.h b/src/components/application_manager/include/application_manager/rpc_handler_impl.h index b7e74c5ab3..e1dc9e6c5d 100644 --- a/src/components/application_manager/include/application_manager/rpc_handler_impl.h +++ b/src/components/application_manager/include/application_manager/rpc_handler_impl.h @@ -154,12 +154,18 @@ class RPCHandlerImpl : public RPCHandler, ns_smart_device_link::ns_smart_objects::SmartObject& output, utils::SemanticVersion& message_version); + bool ValidateRpcSO(smart_objects::SmartObject& message, + utils::SemanticVersion& msg_version, + rpc::ValidationReport& report_out, + bool allow_unknown_parameters) OVERRIDE; + private: void ProcessMessageFromMobile(const std::shared_ptr<Message> message); void ProcessMessageFromHMI(const std::shared_ptr<Message> message); bool ConvertMessageToSO(const Message& message, smart_objects::SmartObject& output, - const bool remove_unknown_parameters = true); + const bool allow_unknown_parameters = false, + const bool validate_params = true); std::shared_ptr<Message> ConvertRawMsgToMessage( const ::protocol_handler::RawMessagePtr message); hmi_apis::HMI_API& hmi_so_factory(); diff --git a/src/components/application_manager/include/application_manager/rpc_service_impl.h b/src/components/application_manager/include/application_manager/rpc_service_impl.h index 848e9645e7..516b8abb8b 100644 --- a/src/components/application_manager/include/application_manager/rpc_service_impl.h +++ b/src/components/application_manager/include/application_manager/rpc_service_impl.h @@ -132,7 +132,7 @@ class RPCServiceImpl : public RPCService, private: bool ConvertSOtoMessage(const smart_objects::SmartObject& message, Message& output, - const bool remove_unknown_parameters = true); + const bool allow_unknown_parameters = false); hmi_apis::HMI_API& hmi_so_factory(); mobile_apis::MOBILE_API& mobile_so_factory(); diff --git a/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/commands/mobile/on_app_service_data_notification_from_mobile.cc b/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/commands/mobile/on_app_service_data_notification_from_mobile.cc index 1328e128d4..7bb62d298d 100644 --- a/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/commands/mobile/on_app_service_data_notification_from_mobile.cc +++ b/src/components/application_manager/rpc_plugins/app_service_rpc_plugin/src/commands/mobile/on_app_service_data_notification_from_mobile.cc @@ -61,7 +61,7 @@ void OnAppServiceDataNotificationFromMobile::Run() { MessageHelper::PrintSmartObject(*message_); std::string service_type = - (*message_)[strings::msg_params][strings::app_service_manifest] + (*message_)[strings::msg_params][strings::service_data] [strings::service_type].asString(); ApplicationSharedPtr app = application_manager_.application(connection_key()); diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc index 1eeaa8f739..735741814a 100644 --- a/src/components/application_manager/src/application_manager_impl.cc +++ b/src/components/application_manager/src/application_manager_impl.cc @@ -2269,7 +2269,7 @@ bool ApplicationManagerImpl::Stop() { bool ApplicationManagerImpl::ConvertSOtoMessage( const smart_objects::SmartObject& message, Message& output, - const bool remove_unknown_parameters) { + const bool allow_unknown_parameters) { LOG4CXX_AUTO_TRACE(logger_); if (smart_objects::SmartType_Null == message.getType() || @@ -2295,7 +2295,7 @@ bool ApplicationManagerImpl::ConvertSOtoMessage( case 0: { if (protocol_version == 1) { if (!formatters::CFormatterJsonSDLRPCv1::toString( - message, output_string, remove_unknown_parameters)) { + message, output_string, !allow_unknown_parameters)) { LOG4CXX_WARN(logger_, "Failed to serialize smart object"); return false; } @@ -2303,7 +2303,7 @@ bool ApplicationManagerImpl::ConvertSOtoMessage( protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_1); } else { if (!formatters::CFormatterJsonSDLRPCv2::toString( - message, output_string, remove_unknown_parameters)) { + message, output_string, !allow_unknown_parameters)) { LOG4CXX_WARN(logger_, "Failed to serialize smart object"); return false; } @@ -2316,7 +2316,7 @@ bool ApplicationManagerImpl::ConvertSOtoMessage( } case 1: { if (!formatters::FormatterJsonRpc::ToString( - message, output_string, remove_unknown_parameters)) { + message, output_string, !allow_unknown_parameters)) { LOG4CXX_WARN(logger_, "Failed to serialize smart object"); return false; } diff --git a/src/components/application_manager/src/rpc_handler_impl.cc b/src/components/application_manager/src/rpc_handler_impl.cc index 6374e2a955..2574da5fb5 100644 --- a/src/components/application_manager/src/rpc_handler_impl.cc +++ b/src/components/application_manager/src/rpc_handler_impl.cc @@ -65,7 +65,7 @@ void RPCHandlerImpl::ProcessMessageFromMobile( #endif // TELEMETRY_MONITOR smart_objects::SmartObjectSPtr so_from_mobile = std::make_shared<smart_objects::SmartObject>(); - bool remove_unknown_parameters = true; + bool allow_unknown_parameters = false; DCHECK_OR_RETURN_VOID(so_from_mobile); if (!so_from_mobile) { LOG4CXX_ERROR(logger_, "Null pointer"); @@ -81,11 +81,11 @@ void RPCHandlerImpl::ProcessMessageFromMobile( LOG4CXX_DEBUG(logger_, "Allowing unknown parameters for request function " << message->function_id()); - remove_unknown_parameters = false; + allow_unknown_parameters = true; } if (!ConvertMessageToSO( - *message, *so_from_mobile, remove_unknown_parameters)) { + *message, *so_from_mobile, allow_unknown_parameters, !rpc_passing)) { LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); return; } @@ -106,7 +106,7 @@ void RPCHandlerImpl::ProcessMessageFromMobile( commands::Command::SOURCE_MOBILE, message_type)) { // Since PassThrough failed, refiltering the message - if (!ConvertMessageToSO(*message, *so_from_mobile, true)) { + if (!ConvertMessageToSO(*message, *so_from_mobile)) { LOG4CXX_ERROR(logger_, "Cannot create smart object from message"); return; } @@ -134,7 +134,7 @@ void RPCHandlerImpl::ProcessMessageFromHMI( LOG4CXX_AUTO_TRACE(logger_); smart_objects::SmartObjectSPtr smart_object = std::make_shared<smart_objects::SmartObject>(); - bool remove_unknown_parameters = true; + bool allow_unknown_parameters = false; if (!smart_object) { LOG4CXX_ERROR(logger_, "Null pointer"); return; @@ -152,10 +152,10 @@ void RPCHandlerImpl::ProcessMessageFromHMI( logger_, "Allowing unknown parameters for request function " << converted_result[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt()); - remove_unknown_parameters = false; + allow_unknown_parameters = true; } - if (!ConvertMessageToSO(*message, *smart_object, remove_unknown_parameters)) { + if (!ConvertMessageToSO(*message, *smart_object, allow_unknown_parameters)) { if (application_manager::MessageType::kResponse == (*smart_object)[strings::params][strings::message_type].asInt()) { (*smart_object).erase(strings::msg_params); @@ -283,7 +283,8 @@ void RPCHandlerImpl::GetMessageVersion( bool RPCHandlerImpl::ConvertMessageToSO( const Message& message, ns_smart_device_link::ns_smart_objects::SmartObject& output, - const bool remove_unknown_parameters) { + const bool allow_unknown_parameters, + const bool validate_params) { LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "\t\t\tMessage to convert: protocol " @@ -317,11 +318,9 @@ bool RPCHandlerImpl::ConvertMessageToSO( } if (!conversion_result || - !mobile_so_factory().attachSchema( - output, remove_unknown_parameters, msg_version) || - ((output.validate(&report, msg_version) != - smart_objects::errors::OK && - remove_unknown_parameters))) { + (validate_params && + !ValidateRpcSO( + output, msg_version, report, allow_unknown_parameters))) { LOG4CXX_WARN(logger_, "Failed to parse string to smart object with API version " << msg_version.toString() << " : " @@ -338,8 +337,10 @@ bool RPCHandlerImpl::ConvertMessageToSO( rpc::PrettyFormat(report); app_manager_.GetRPCService().ManageMobileCommand( response, commands::Command::SOURCE_SDL); + return false; } + LOG4CXX_DEBUG(logger_, "Convertion result for sdl object is true function_id " << output[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt()); @@ -388,9 +389,12 @@ bool RPCHandlerImpl::ConvertMessageToSO( rpc::ValidationReport report("RPC"); - if (output.validate(&report) != smart_objects::errors::OK) { + utils::SemanticVersion empty_version; + if (validate_params && + output.validate(&report, empty_version, allow_unknown_parameters) != + smart_objects::errors::OK) { LOG4CXX_ERROR(logger_, - "Incorrect parameter from HMI" + "Incorrect parameter from HMI - " << rpc::PrettyFormat(report)); output.erase(strings::msg_params); @@ -449,6 +453,20 @@ bool RPCHandlerImpl::ConvertMessageToSO( return true; } +bool RPCHandlerImpl::ValidateRpcSO(smart_objects::SmartObject& message, + utils::SemanticVersion& msg_version, + rpc::ValidationReport& report_out, + bool allow_unknown_parameters) { + if (!mobile_so_factory().attachSchema( + message, !allow_unknown_parameters, msg_version) || + message.validate(&report_out, msg_version, allow_unknown_parameters) != + smart_objects::errors::OK) { + LOG4CXX_WARN(logger_, "Failed to parse string to smart object"); + return false; + } + return true; +} + std::shared_ptr<Message> RPCHandlerImpl::ConvertRawMsgToMessage( const protocol_handler::RawMessagePtr message) { LOG4CXX_AUTO_TRACE(logger_); diff --git a/src/components/application_manager/src/rpc_passing_handler.cc b/src/components/application_manager/src/rpc_passing_handler.cc index 560418e910..8d93659a27 100644 --- a/src/components/application_manager/src/rpc_passing_handler.cc +++ b/src/components/application_manager/src/rpc_passing_handler.cc @@ -38,6 +38,7 @@ #include "application_manager/application.h" #include "application_manager/application_manager.h" #include "application_manager/rpc_passing_handler.h" +#include "application_manager/rpc_handler.h" #include "application_manager/commands/command_impl.h" #include "application_manager/message_helper.h" #include "application_manager/smart_object_keys.h" @@ -145,8 +146,12 @@ bool RPCPassingHandler::RPCPassThrough(smart_objects::SmartObject rpc_message) { } rpc_request_queue_lock_.Release(); RemoveRequestTimer(correlation_id); - auto result_code = static_cast<mobile_apis::Result::eType>( - rpc_message[strings::msg_params][strings::result_code].asInt()); + + mobile_apis::Result::eType result_code; + smart_objects::EnumConversionHelper<mobile_apis::Result::eType>:: + StringToEnum( + rpc_message[strings::msg_params][strings::result_code].asString(), + &result_code); if (result_code == mobile_apis::Result::UNSUPPORTED_REQUEST) { LOG4CXX_DEBUG(logger_, "Service sent UNSUPPORTED_REQUEST"); @@ -228,6 +233,33 @@ void RPCPassingHandler::ForwardRequestToCore(uint32_t correlation_id) { std::make_shared<smart_objects::SmartObject>(message); rpc_request_queue.erase(correlation_id); rpc_request_queue_lock_.Release(); + + // Validate rpc message before forwarding to core + rpc::ValidationReport report("RPC"); + uint32_t connection_key = + message[strings::params][strings::connection_key].asUInt(); + int32_t function_id = message[strings::params][strings::function_id].asInt(); + auto app_ptr = app_manager_.application(connection_key); + utils::SemanticVersion msg_version(0, 0, 0); + if (app_ptr) { + msg_version = app_ptr->msg_version(); + } + + if (!app_manager_.GetRPCHandler().ValidateRpcSO( + message, msg_version, report, false)) { + std::shared_ptr<smart_objects::SmartObject> response( + MessageHelper::CreateNegativeResponse( + connection_key, + function_id, + correlation_id, + mobile_apis::Result::INVALID_DATA)); + + (*response)[strings::msg_params][strings::info] = rpc::PrettyFormat(report); + app_manager_.GetRPCService().ManageMobileCommand( + response, commands::Command::SOURCE_SDL); + return; + } + app_manager_.GetRPCService().ManageMobileCommand( result, commands::Command::SOURCE_MOBILE); } diff --git a/src/components/application_manager/src/rpc_service_impl.cc b/src/components/application_manager/src/rpc_service_impl.cc index d8329ba8cf..dfb5839764 100644 --- a/src/components/application_manager/src/rpc_service_impl.cc +++ b/src/components/application_manager/src/rpc_service_impl.cc @@ -388,7 +388,7 @@ void RPCServiceImpl::SendMessageToMobile( const bool is_result_code_exists = (*message)[strings::msg_params].keyExists(strings::result_code); - bool remove_unknown_parameters = true; + bool allow_unknown_parameters = false; if (!app) { LOG4CXX_ERROR(logger_, "No application associated with connection key"); @@ -431,7 +431,7 @@ void RPCServiceImpl::SendMessageToMobile( LOG4CXX_DEBUG(logger_, "Allowing unknown parameters for response function " << function_id); - remove_unknown_parameters = false; + allow_unknown_parameters = true; } if (rpc_passing && @@ -441,10 +441,10 @@ void RPCServiceImpl::SendMessageToMobile( (*message)[jhs::S_PARAMS][jhs::S_CORRELATION_ID].asUInt(), commands::Command::CommandSource::SOURCE_SDL, (*message)[jhs::S_PARAMS][jhs::S_MESSAGE_TYPE].asInt())) { - remove_unknown_parameters = true; + allow_unknown_parameters = false; } if (!ConvertSOtoMessage( - (*message), (*message_to_send), remove_unknown_parameters)) { + (*message), (*message_to_send), allow_unknown_parameters)) { LOG4CXX_WARN(logger_, "Can't send msg to Mobile: failed to create string"); return; } @@ -523,7 +523,7 @@ void RPCServiceImpl::SendMessageToHMI( return; } - bool remove_unknown_parameters = true; + bool allow_unknown_parameters = false; // SmartObject |message| has no way to declare priority for now std::shared_ptr<Message> message_to_send( new Message(protocol_handler::MessagePriority::kDefault)); @@ -543,11 +543,11 @@ void RPCServiceImpl::SendMessageToHMI( "Allowing unknown parameters for response function " << (*message)[jhs::S_PARAMS][jhs::S_FUNCTION_ID].asInt()); - remove_unknown_parameters = false; + allow_unknown_parameters = true; } if (!ConvertSOtoMessage( - *message, *message_to_send, remove_unknown_parameters)) { + *message, *message_to_send, allow_unknown_parameters)) { LOG4CXX_WARN(logger_, "Cannot send message to HMI: failed to create string"); return; @@ -605,7 +605,7 @@ void RPCServiceImpl::set_hmi_message_handler( bool RPCServiceImpl::ConvertSOtoMessage( const ns_smart_device_link::ns_smart_objects::SmartObject& message, Message& output, - const bool remove_unknown_parameters) { + const bool allow_unknown_parameters) { LOG4CXX_AUTO_TRACE(logger_); if (smart_objects::SmartType_Null == message.getType() || @@ -631,7 +631,7 @@ bool RPCServiceImpl::ConvertSOtoMessage( case 0: { if (protocol_version == 1) { if (!formatters::CFormatterJsonSDLRPCv1::toString( - message, output_string, remove_unknown_parameters)) { + message, output_string, !allow_unknown_parameters)) { LOG4CXX_WARN(logger_, "Failed to serialize smart object"); return false; } @@ -639,7 +639,7 @@ bool RPCServiceImpl::ConvertSOtoMessage( protocol_handler::MajorProtocolVersion::PROTOCOL_VERSION_1); } else { if (!formatters::CFormatterJsonSDLRPCv2::toString( - message, output_string, remove_unknown_parameters)) { + message, output_string, !allow_unknown_parameters)) { LOG4CXX_WARN(logger_, "Failed to serialize smart object"); return false; } @@ -652,7 +652,7 @@ bool RPCServiceImpl::ConvertSOtoMessage( } case 1: { if (!formatters::FormatterJsonRpc::ToString( - message, output_string, remove_unknown_parameters)) { + message, output_string, !allow_unknown_parameters)) { LOG4CXX_WARN(logger_, "Failed to serialize smart object"); return false; } diff --git a/src/components/include/application_manager/rpc_handler.h b/src/components/include/application_manager/rpc_handler.h index 9b6428f32d..2ada9e7901 100644 --- a/src/components/include/application_manager/rpc_handler.h +++ b/src/components/include/application_manager/rpc_handler.h @@ -52,6 +52,11 @@ class RPCHandler #endif // TELEMETRY_MONITOR { public: + virtual bool ValidateRpcSO(smart_objects::SmartObject& message, + utils::SemanticVersion& msg_version, + rpc::ValidationReport& report_out, + bool allow_unknown_parameters) = 0; + virtual ~RPCHandler() {} }; diff --git a/src/components/smart_objects/include/smart_objects/always_false_schema_item.h b/src/components/smart_objects/include/smart_objects/always_false_schema_item.h index bfa39af10a..05c53ec582 100644 --- a/src/components/smart_objects/include/smart_objects/always_false_schema_item.h +++ b/src/components/smart_objects/include/smart_objects/always_false_schema_item.h @@ -53,12 +53,17 @@ class CAlwaysFalseSchemaItem : public ISchemaItem { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = - utils::SemanticVersion()) OVERRIDE; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) OVERRIDE; private: CAlwaysFalseSchemaItem(); diff --git a/src/components/smart_objects/include/smart_objects/always_true_schema_item.h b/src/components/smart_objects/include/smart_objects/always_true_schema_item.h index 4750c280e5..a2d305d0f9 100644 --- a/src/components/smart_objects/include/smart_objects/always_true_schema_item.h +++ b/src/components/smart_objects/include/smart_objects/always_true_schema_item.h @@ -53,12 +53,17 @@ class CAlwaysTrueSchemaItem : public ISchemaItem { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = - utils::SemanticVersion()) OVERRIDE; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) OVERRIDE; private: CAlwaysTrueSchemaItem(); diff --git a/src/components/smart_objects/include/smart_objects/array_schema_item.h b/src/components/smart_objects/include/smart_objects/array_schema_item.h index b365a48638..7706b6e091 100644 --- a/src/components/smart_objects/include/smart_objects/array_schema_item.h +++ b/src/components/smart_objects/include/smart_objects/array_schema_item.h @@ -68,12 +68,17 @@ class CArraySchemaItem : public ISchemaItem { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = - utils::SemanticVersion()) OVERRIDE; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) OVERRIDE; /** * @brief Apply schema. diff --git a/src/components/smart_objects/include/smart_objects/default_shema_item.h b/src/components/smart_objects/include/smart_objects/default_shema_item.h index 5978fcb282..beeeaac81f 100644 --- a/src/components/smart_objects/include/smart_objects/default_shema_item.h +++ b/src/components/smart_objects/include/smart_objects/default_shema_item.h @@ -53,12 +53,17 @@ class CDefaultSchemaItem : public ISchemaItem { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = - utils::SemanticVersion()) OVERRIDE; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) OVERRIDE; /** * @brief Set default value to an object. @@ -105,7 +110,8 @@ template <typename Type> errors::eType CDefaultSchemaItem<Type>::validate( const SmartObject& Object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { if (getSmartType() != Object.getType()) { std::string validation_info = "Incorrect type, expected: " + SmartObject::typeToString(getSmartType()) + diff --git a/src/components/smart_objects/include/smart_objects/enum_schema_item.h b/src/components/smart_objects/include/smart_objects/enum_schema_item.h index dfa0a4baeb..2a27f765d2 100644 --- a/src/components/smart_objects/include/smart_objects/enum_schema_item.h +++ b/src/components/smart_objects/include/smart_objects/enum_schema_item.h @@ -108,12 +108,17 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = - utils::SemanticVersion()) OVERRIDE; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) OVERRIDE; /** * @brief Return the correct history signature based on message version. * @param signatures Vector reference of enums history items. @@ -310,10 +315,14 @@ template <typename EnumType> errors::eType TEnumSchemaItem<EnumType>::validate( const SmartObject& Object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { if (SmartType_Integer != Object.getType()) { std::string validation_info; if (SmartType_String == Object.getType()) { + if (allow_unknown_enums) { + return errors::OK; + } validation_info = "Invalid enum value: " + Object.asString(); } else { validation_info = "Incorrect type, expected: " + diff --git a/src/components/smart_objects/include/smart_objects/number_schema_item.h b/src/components/smart_objects/include/smart_objects/number_schema_item.h index 6481605daf..b3e227e0f1 100644 --- a/src/components/smart_objects/include/smart_objects/number_schema_item.h +++ b/src/components/smart_objects/include/smart_objects/number_schema_item.h @@ -70,12 +70,17 @@ class TNumberSchemaItem : public CDefaultSchemaItem<NumberType> { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = - utils::SemanticVersion()) OVERRIDE; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) OVERRIDE; private: /** @@ -137,7 +142,8 @@ template <typename NumberType> errors::eType TNumberSchemaItem<NumberType>::validate( const SmartObject& Object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { if (!isValidNumberType(Object.getType())) { SmartType expectedType = (typeid(double) == typeid(Object.getType())) ? SmartType_Double diff --git a/src/components/smart_objects/include/smart_objects/object_schema_item.h b/src/components/smart_objects/include/smart_objects/object_schema_item.h index 27937ee17c..7b57792c1e 100644 --- a/src/components/smart_objects/include/smart_objects/object_schema_item.h +++ b/src/components/smart_objects/include/smart_objects/object_schema_item.h @@ -109,12 +109,17 @@ class CObjectSchemaItem : public ISchemaItem { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = - utils::SemanticVersion()) OVERRIDE; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) OVERRIDE; /** * @brief Apply schema. * @param Object Object to apply schema. diff --git a/src/components/smart_objects/include/smart_objects/schema_item.h b/src/components/smart_objects/include/smart_objects/schema_item.h index 0c1b3f75b8..fa5f6d3adc 100644 --- a/src/components/smart_objects/include/smart_objects/schema_item.h +++ b/src/components/smart_objects/include/smart_objects/schema_item.h @@ -58,13 +58,18 @@ class ISchemaItem { * @param Object Object to validate. * @param report__ object for reporting errors during validation * message if an error occurs - * @param MessageVersion to check mobile RPC version against RPC Spec Histor + * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ virtual errors::eType validate( const SmartObject& Object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = utils::SemanticVersion()); + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false); /** * @brief Set default value to an object. diff --git a/src/components/smart_objects/include/smart_objects/smart_object.h b/src/components/smart_objects/include/smart_objects/smart_object.h index 2abc221972..b862d25a17 100644 --- a/src/components/smart_objects/include/smart_objects/smart_object.h +++ b/src/components/smart_objects/include/smart_objects/smart_object.h @@ -676,11 +676,16 @@ class SmartObject FINAL { * * @param report__ object for reporting errors during validation * @param messageVersion of the mobile app to check against RPC Spec Schema + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return Result of validation. */ errors::eType validate( rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = utils::SemanticVersion()); + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false); /** * @brief Sets new schema diff --git a/src/components/smart_objects/include/smart_objects/smart_schema.h b/src/components/smart_objects/include/smart_objects/smart_schema.h index 41737fed25..ece2696539 100644 --- a/src/components/smart_objects/include/smart_objects/smart_schema.h +++ b/src/components/smart_objects/include/smart_objects/smart_schema.h @@ -66,12 +66,17 @@ class CSmartSchema FINAL { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& messageVersion = - utils::SemanticVersion()) const; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& messageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) const; /** * @brief Set new root schema item. diff --git a/src/components/smart_objects/include/smart_objects/string_schema_item.h b/src/components/smart_objects/include/smart_objects/string_schema_item.h index 5b37db584d..7104ff47a9 100644 --- a/src/components/smart_objects/include/smart_objects/string_schema_item.h +++ b/src/components/smart_objects/include/smart_objects/string_schema_item.h @@ -65,12 +65,17 @@ class CStringSchemaItem : public CDefaultSchemaItem<std::string> { * @param Object Object to validate. * @param report__ object for reporting errors during validation * @param MessageVersion to check mobile RPC version against RPC Spec History + * @param allow_unknown_enums + * false - unknown enum values (left as string values after applySchema) + * will be considered invalid. + * true - such values will be considered valid. * @return ns_smart_objects::errors::eType **/ - errors::eType validate(const SmartObject& Object, - rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion = - utils::SemanticVersion()) OVERRIDE; + errors::eType validate( + const SmartObject& Object, + rpc::ValidationReport* report__, + const utils::SemanticVersion& MessageVersion = utils::SemanticVersion(), + const bool allow_unknown_enums = false) OVERRIDE; private: /** diff --git a/src/components/smart_objects/src/always_false_schema_item.cc b/src/components/smart_objects/src/always_false_schema_item.cc index ca247eed09..4f8f4584af 100644 --- a/src/components/smart_objects/src/always_false_schema_item.cc +++ b/src/components/smart_objects/src/always_false_schema_item.cc @@ -44,7 +44,8 @@ std::shared_ptr<CAlwaysFalseSchemaItem> CAlwaysFalseSchemaItem::create() { errors::eType CAlwaysFalseSchemaItem::validate( const SmartObject& Object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { report__->set_validation_info("Generic error"); return errors::ERROR; } diff --git a/src/components/smart_objects/src/always_true_schema_item.cc b/src/components/smart_objects/src/always_true_schema_item.cc index 983733165c..855bfef2a0 100644 --- a/src/components/smart_objects/src/always_true_schema_item.cc +++ b/src/components/smart_objects/src/always_true_schema_item.cc @@ -42,7 +42,8 @@ std::shared_ptr<CAlwaysTrueSchemaItem> CAlwaysTrueSchemaItem::create() { errors::eType CAlwaysTrueSchemaItem::validate( const SmartObject& Object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { return errors::OK; } diff --git a/src/components/smart_objects/src/array_schema_item.cc b/src/components/smart_objects/src/array_schema_item.cc index be5fc2b83a..1671a97644 100644 --- a/src/components/smart_objects/src/array_schema_item.cc +++ b/src/components/smart_objects/src/array_schema_item.cc @@ -45,7 +45,8 @@ std::shared_ptr<CArraySchemaItem> CArraySchemaItem::create( errors::eType CArraySchemaItem::validate( const SmartObject& Object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { if (SmartType_Array != Object.getType()) { std::string validation_info = "Incorrect type, expected: " + SmartObject::typeToString(SmartType_Array) + @@ -80,7 +81,8 @@ errors::eType CArraySchemaItem::validate( const errors::eType result = mElementSchemaItem->validate(Object.getElement(i), &report__->ReportSubobject(strVal.str()), - MessageVersion); + MessageVersion, + allow_unknown_enums); if (errors::OK != result) { return result; } diff --git a/src/components/smart_objects/src/object_schema_item.cc b/src/components/smart_objects/src/object_schema_item.cc index b32757db7a..21d2316e48 100644 --- a/src/components/smart_objects/src/object_schema_item.cc +++ b/src/components/smart_objects/src/object_schema_item.cc @@ -110,7 +110,8 @@ std::shared_ptr<CObjectSchemaItem> CObjectSchemaItem::create( errors::eType CObjectSchemaItem::validate( const SmartObject& object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { if (SmartType_Map != object.getType()) { std::string validation_info = "Incorrect type, expected: " + SmartObject::typeToString(SmartType_Map) + @@ -142,8 +143,11 @@ errors::eType CObjectSchemaItem::validate( errors::eType result = errors::OK; // Check if MessageVersion matches schema version - result = correct_member.mSchemaItem->validate( - field, &report__->ReportSubobject(key), MessageVersion); + result = + correct_member.mSchemaItem->validate(field, + &report__->ReportSubobject(key), + MessageVersion, + allow_unknown_enums); if (errors::OK != result) { return result; } diff --git a/src/components/smart_objects/src/schema_item.cc b/src/components/smart_objects/src/schema_item.cc index fbab17f32d..8c40e2c7bd 100644 --- a/src/components/smart_objects/src/schema_item.cc +++ b/src/components/smart_objects/src/schema_item.cc @@ -38,7 +38,8 @@ namespace ns_smart_objects { errors::eType ISchemaItem::validate( const SmartObject& object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { return errors::ERROR; } diff --git a/src/components/smart_objects/src/smart_object.cc b/src/components/smart_objects/src/smart_object.cc index 3235dd619e..ef5dc787be 100644 --- a/src/components/smart_objects/src/smart_object.cc +++ b/src/components/smart_objects/src/smart_object.cc @@ -878,8 +878,10 @@ bool SmartObject::isValid() const { errors::eType SmartObject::validate( rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { - return m_schema.validate(*this, report__, MessageVersion); + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { + return m_schema.validate( + *this, report__, MessageVersion, allow_unknown_enums); } void SmartObject::setSchema(const CSmartSchema& schema) { diff --git a/src/components/smart_objects/src/smart_schema.cc b/src/components/smart_objects/src/smart_schema.cc index dc0f1cbe31..4ab5e5ff23 100644 --- a/src/components/smart_objects/src/smart_schema.cc +++ b/src/components/smart_objects/src/smart_schema.cc @@ -43,8 +43,10 @@ CSmartSchema::CSmartSchema(const ISchemaItemPtr SchemaItem) errors::eType CSmartSchema::validate( const SmartObject& object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) const { - return mSchemaItem->validate(object, report__, MessageVersion); + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) const { + return mSchemaItem->validate( + object, report__, MessageVersion, allow_unknown_enums); } void CSmartSchema::setSchemaItem(const ISchemaItemPtr schemaItem) { diff --git a/src/components/smart_objects/src/string_schema_item.cc b/src/components/smart_objects/src/string_schema_item.cc index 0288ad85e8..e2ebde1861 100644 --- a/src/components/smart_objects/src/string_schema_item.cc +++ b/src/components/smart_objects/src/string_schema_item.cc @@ -49,7 +49,8 @@ std::shared_ptr<CStringSchemaItem> CStringSchemaItem::create( errors::eType CStringSchemaItem::validate( const SmartObject& Object, rpc::ValidationReport* report__, - const utils::SemanticVersion& MessageVersion) { + const utils::SemanticVersion& MessageVersion, + const bool allow_unknown_enums) { if (SmartType_String != Object.getType()) { std::string validation_info = "Incorrect type, expected: " + SmartObject::typeToString(SmartType_String) + |