/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_ContentAnalysisIPCTypes_h #define mozilla_ContentAnalysisIPCTypes_h #include "ipc/EnumSerializer.h" #include "ipc/IPCMessageUtilsSpecializations.h" #include "js/PropertyAndElement.h" #include "mozilla/Variant.h" #include "nsIContentAnalysis.h" namespace mozilla { namespace contentanalysis { enum class NoContentAnalysisResult : uint8_t { ALLOW_DUE_TO_CONTENT_ANALYSIS_NOT_ACTIVE, ALLOW_DUE_TO_CONTEXT_EXEMPT_FROM_CONTENT_ANALYSIS, ALLOW_DUE_TO_COULD_NOT_GET_DATA, DENY_DUE_TO_CANCELED, DENY_DUE_TO_INVALID_JSON_RESPONSE, DENY_DUE_TO_OTHER_ERROR, LAST_VALUE }; class ContentAnalysisResult : public nsIContentAnalysisResult { NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSICONTENTANALYSISRESULT public: static RefPtr FromAction( nsIContentAnalysisResponse::Action aAction) { auto result = RefPtr(new ContentAnalysisResult(aAction)); return result; } static RefPtr FromNoResult( NoContentAnalysisResult aResult) { auto result = RefPtr(new ContentAnalysisResult(aResult)); return result; } static RefPtr FromJSONResponse( const JS::Handle& aValue, JSContext* aCx) { if (aValue.isObject()) { auto* obj = aValue.toObjectOrNull(); JS::Handle handle = JS::Handle::fromMarkedLocation(&obj); JS::Rooted actionValue(aCx); if (JS_GetProperty(aCx, handle, "action", &actionValue)) { if (actionValue.isNumber()) { double actionNumber = actionValue.toNumber(); return FromAction( static_cast(actionNumber)); } } } return FromNoResult( NoContentAnalysisResult::DENY_DUE_TO_INVALID_JSON_RESPONSE); } static RefPtr FromJSONContentAnalysisResponse( const JS::Handle& aValue, JSContext* aCx) { if (aValue.isObject()) { auto* obj = aValue.toObjectOrNull(); JS::Handle handle = JS::Handle::fromMarkedLocation(&obj); JS::Rooted shouldAllowValue(aCx); if (JS_GetProperty(aCx, handle, "shouldAllowContent", &shouldAllowValue)) { if (shouldAllowValue.isTrue()) { return FromAction(nsIContentAnalysisResponse::Action::eAllow); } else if (shouldAllowValue.isFalse()) { return FromAction(nsIContentAnalysisResponse::Action::eBlock); } else { return FromNoResult(NoContentAnalysisResult::DENY_DUE_TO_OTHER_ERROR); } } } return FromNoResult( NoContentAnalysisResult::DENY_DUE_TO_INVALID_JSON_RESPONSE); } static RefPtr FromContentAnalysisResponse( nsIContentAnalysisResponse* aResponse) { bool shouldAllowContent = false; DebugOnly rv = aResponse->GetShouldAllowContent(&shouldAllowContent); MOZ_ASSERT(NS_SUCCEEDED(rv)); if (shouldAllowContent) { return FromAction(nsIContentAnalysisResponse::Action::eAllow); } else { return FromAction(nsIContentAnalysisResponse::Action::eBlock); } } private: explicit ContentAnalysisResult(nsIContentAnalysisResponse::Action aAction) : mValue(aAction) {} explicit ContentAnalysisResult(NoContentAnalysisResult aResult) : mValue(aResult) {} virtual ~ContentAnalysisResult() = default; Variant mValue; friend struct IPC::ParamTraits; friend struct IPC::ParamTraits; friend struct IPC::ParamTraits>; }; } // namespace contentanalysis } // namespace mozilla namespace IPC { template <> struct ParamTraits : public ContiguousEnumSerializer< mozilla::contentanalysis::NoContentAnalysisResult, static_cast(0), mozilla::contentanalysis::NoContentAnalysisResult::LAST_VALUE> {}; template <> struct ParamTraits : public ContiguousEnumSerializerInclusive< nsIContentAnalysisResponse::Action, nsIContentAnalysisResponse::Action::eUnspecified, nsIContentAnalysisResponse::Action::eCanceled> {}; template <> struct ParamTraits { typedef mozilla::contentanalysis::ContentAnalysisResult paramType; static void Write(MessageWriter* aWriter, const paramType& aParam) { WriteParam(aWriter, aParam.mValue); } static bool Read(MessageReader* aReader, paramType* aResult) { return ReadParam(aReader, &(aResult->mValue)); } }; template <> struct ParamTraits { typedef mozilla::contentanalysis::ContentAnalysisResult paramType; static void Write(MessageWriter* aWriter, const paramType* aParam) { if (!aParam) { WriteParam(aWriter, true); return; } WriteParam(aWriter, false); WriteParam(aWriter, aParam->mValue); } static bool Read(MessageReader* aReader, RefPtr* aResult) { bool isNull = false; if (!ReadParam(aReader, &isNull)) { return false; } if (isNull) { *aResult = nullptr; return true; } *aResult = mozilla::contentanalysis::ContentAnalysisResult::FromNoResult( mozilla::contentanalysis::NoContentAnalysisResult:: DENY_DUE_TO_OTHER_ERROR); return ReadParam(aReader, &((*aResult)->mValue)); } }; } // namespace IPC #endif // mozilla_ContentAnalysisIPCTypes_h