From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../tests/gtest/TestContentAnalysis.cpp | 132 +++++++ .../tests/gtest/TestContentAnalysis.h | 24 ++ .../tests/gtest/TestContentAnalysisMisbehaving.cpp | 416 +++++++++++++++++++++ .../tests/gtest/TestContentAnalysisUtils.cpp | 75 ++++ .../contentanalysis/tests/gtest/agent/moz.build | 40 ++ .../contentanalysis/tests/gtest/allowedFile.txt | 1 + .../contentanalysis/tests/gtest/blockedFile.txt | 1 + .../contentanalysis/tests/gtest/moz.build | 23 ++ 8 files changed, 712 insertions(+) create mode 100644 toolkit/components/contentanalysis/tests/gtest/TestContentAnalysis.cpp create mode 100644 toolkit/components/contentanalysis/tests/gtest/TestContentAnalysis.h create mode 100644 toolkit/components/contentanalysis/tests/gtest/TestContentAnalysisMisbehaving.cpp create mode 100644 toolkit/components/contentanalysis/tests/gtest/TestContentAnalysisUtils.cpp create mode 100644 toolkit/components/contentanalysis/tests/gtest/agent/moz.build create mode 100644 toolkit/components/contentanalysis/tests/gtest/allowedFile.txt create mode 100644 toolkit/components/contentanalysis/tests/gtest/blockedFile.txt create mode 100644 toolkit/components/contentanalysis/tests/gtest/moz.build (limited to 'toolkit/components/contentanalysis/tests') diff --git a/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysis.cpp b/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysis.cpp new file mode 100644 index 0000000000..1cf6d8fc22 --- /dev/null +++ b/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysis.cpp @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 https://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Assertions.h" +#include "mozilla/CmdLineAndEnvUtils.h" +#include "content_analysis/sdk/analysis_client.h" +#include "TestContentAnalysis.h" +#include +#include + +using namespace content_analysis::sdk; + +MozAgentInfo LaunchAgentNormal(const wchar_t* aToBlock) { + nsString cmdLineArguments; + if (aToBlock && aToBlock[0] != 0) { + cmdLineArguments.Append(L" --toblock=.*"); + cmdLineArguments.Append(aToBlock); + cmdLineArguments.Append(L".*"); + } + cmdLineArguments.Append(L" --user"); + cmdLineArguments.Append(L" --path="); + nsString pipeName; + GeneratePipeName(L"contentanalysissdk-gtest-", pipeName); + cmdLineArguments.Append(pipeName); + MozAgentInfo agentInfo; + LaunchAgentWithCommandLineArguments(cmdLineArguments, pipeName, agentInfo); + return agentInfo; +} + +TEST(ContentAnalysis, TextShouldNotBeBlocked) +{ + auto MozAgentInfo = LaunchAgentNormal(L"block"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("should succeed"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + ASSERT_STREQ("request token", response.request_token().c_str()); + ASSERT_EQ(1, response.results().size()); + ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS, + response.results().Get(0).status()); + ASSERT_EQ(0, response.results().Get(0).triggered_rules_size()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysis, TextShouldBeBlocked) +{ + auto MozAgentInfo = LaunchAgentNormal(L"block"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("should be blocked"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + ASSERT_STREQ("request token", response.request_token().c_str()); + ASSERT_EQ(1, response.results().size()); + ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS, + response.results().Get(0).status()); + ASSERT_EQ(1, response.results().Get(0).triggered_rules_size()); + ASSERT_EQ(ContentAnalysisResponse_Result_TriggeredRule_Action_BLOCK, + response.results().Get(0).triggered_rules(0).action()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysis, FileShouldNotBeBlocked) +{ + auto MozAgentInfo = LaunchAgentNormal(L"block"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_file_path("..\\..\\_tests\\gtest\\allowedFile.txt"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + ASSERT_STREQ("request token", response.request_token().c_str()); + ASSERT_EQ(1, response.results().size()); + ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS, + response.results().Get(0).status()); + ASSERT_EQ(0, response.results().Get(0).triggered_rules_size()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysis, FileShouldBeBlocked) +{ + auto MozAgentInfo = LaunchAgentNormal(L"block"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_file_path("..\\..\\_tests\\gtest\\blockedFile.txt"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + ASSERT_STREQ("request token", response.request_token().c_str()); + ASSERT_EQ(1, response.results().size()); + ASSERT_EQ(ContentAnalysisResponse_Result_Status_SUCCESS, + response.results().Get(0).status()); + ASSERT_EQ(1, response.results().Get(0).triggered_rules_size()); + ASSERT_EQ(ContentAnalysisResponse_Result_TriggeredRule_Action_BLOCK, + response.results().Get(0).triggered_rules(0).action()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} diff --git a/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysis.h b/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysis.h new file mode 100644 index 0000000000..9e31036262 --- /dev/null +++ b/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysis.h @@ -0,0 +1,24 @@ +/* -*- 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_testcontentanalysis_h +#define mozilla_testcontentanalysis_h + +#include + +#include "content_analysis/sdk/analysis_client.h" +#include "gtest/gtest.h" +#include "nsString.h" + +struct MozAgentInfo { + PROCESS_INFORMATION processInfo; + std::unique_ptr client; +}; + +void GeneratePipeName(const wchar_t* prefix, nsString& pipeName); +void LaunchAgentWithCommandLineArguments(const nsString& cmdLineArguments, + const nsString& pipeName, + MozAgentInfo& agentInfo); +#endif diff --git a/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysisMisbehaving.cpp b/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysisMisbehaving.cpp new file mode 100644 index 0000000000..0b005e1f6c --- /dev/null +++ b/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysisMisbehaving.cpp @@ -0,0 +1,416 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 https://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Assertions.h" +#include "mozilla/CmdLineAndEnvUtils.h" +#include "content_analysis/sdk/analysis_client.h" +#include "TestContentAnalysis.h" +#include +#include +#include + +using namespace content_analysis::sdk; + +namespace { +MozAgentInfo LaunchAgentMisbehaving(const wchar_t* mode) { + nsString cmdLineArguments; + cmdLineArguments.Append(L" --misbehave="); + cmdLineArguments.Append(mode); + cmdLineArguments.Append(L" --user"); + cmdLineArguments.Append(L" --path="); + nsString pipeName; + GeneratePipeName(L"contentanalysissdk-gtest-", pipeName); + cmdLineArguments.Append(pipeName); + MozAgentInfo agentInfo; + LaunchAgentWithCommandLineArguments(cmdLineArguments, pipeName, agentInfo); + return agentInfo; +} +} // namespace + +// Disabled for now +/*TEST(ContentAnalysisMisbehaving, LargeResponse) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"largeResponse"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + ASSERT_STREQ("request token", response.request_token().c_str()); + ASSERT_EQ(1001, response.results().size()); + + BOOL terminateResult = ::TerminateProcess(MozAgentInfo.processInfo.hProcess, +0); ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +}*/ + +TEST(ContentAnalysisMisbehaving, InvalidUtf8StringStartByteIsContinuationByte) +{ + auto MozAgentInfo = + LaunchAgentMisbehaving(L"invalidUtf8StringStartByteIsContinuationByte"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + // The protobuf spec says that strings must be valid UTF-8. So it's OK if + // this gets mangled, just want to make sure it doesn't cause a crash + // or invalid memory access or something. + ASSERT_STREQ("\x80\x41\x41\x41", response.request_token().c_str()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, + InvalidUtf8StringEndsInMiddleOfMultibyteSequence) +{ + auto MozAgentInfo = LaunchAgentMisbehaving( + L"invalidUtf8StringEndsInMiddleOfMultibyteSequence"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + // The protobuf spec says that strings must be valid UTF-8. So it's OK if + // this gets mangled, just want to make sure it doesn't cause a crash + // or invalid memory access or something. + ASSERT_STREQ("\x41\xf0\x90\x8d", response.request_token().c_str()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, InvalidUtf8StringMultibyteSequenceTooShort) +{ + auto MozAgentInfo = + LaunchAgentMisbehaving(L"invalidUtf8StringMultibyteSequenceTooShort"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + // The protobuf spec says that strings must be valid UTF-8. So it's OK if + // this gets mangled, just want to make sure it doesn't cause a crash + // or invalid memory access or something. + ASSERT_STREQ("\xf0\x90\x8d\x41", response.request_token().c_str()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, InvalidUtf8StringDecodesToInvalidCodePoint) +{ + auto MozAgentInfo = + LaunchAgentMisbehaving(L"invalidUtf8StringDecodesToInvalidCodePoint"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + // The protobuf spec says that strings must be valid UTF-8. So it's OK if + // this gets mangled, just want to make sure it doesn't cause a crash + // or invalid memory access or something. + ASSERT_STREQ("\xf7\xbf\xbf\xbf", response.request_token().c_str()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, InvalidUtf8StringOverlongEncoding) +{ + auto MozAgentInfo = + LaunchAgentMisbehaving(L"invalidUtf8StringOverlongEncoding"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + // The protobuf spec says that strings must be valid UTF-8. So it's OK if + // this gets mangled, just want to make sure it doesn't cause a crash + // or invalid memory access or something. + ASSERT_STREQ("\xf0\x82\x82\xac", response.request_token().c_str()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, StringWithEmbeddedNull) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"stringWithEmbeddedNull"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + std::string expected("\x41\x00\x41"); + ASSERT_EQ(expected, response.request_token()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, ZeroResults) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"zeroResults"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + ASSERT_EQ(0, response.results().size()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, ResultWithInvalidStatus) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"resultWithInvalidStatus"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + request.set_text_content("unused"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + ASSERT_EQ(1, response.results().size()); + // protobuf will fail to read this because it's an invalid value. + // (and leave status at its default value of 0) + // just make sure we can get the value without throwing + ASSERT_GE(static_cast(response.results(0).status()), 0); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageTruncatedInMiddleOfString) +{ + auto MozAgentInfo = + LaunchAgentMisbehaving(L"messageTruncatedInMiddleOfString"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + // The response is an invalid serialization of protobuf, so this should fail + ASSERT_EQ(-1, MozAgentInfo.client->Send(request, &response)); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageWithInvalidWireType) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"messageWithInvalidWireType"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + // The response is an invalid serialization of protobuf, so this should fail + ASSERT_EQ(-1, MozAgentInfo.client->Send(request, &response)); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageWithUnusedFieldNumber) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"messageWithUnusedFieldNumber"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + ASSERT_EQ(0, MozAgentInfo.client->Send(request, &response)); + // protobuf will read the value and store it in an unused section + // just make sure we can get a value without throwing + ASSERT_STREQ("", response.request_token().c_str()); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageWithWrongStringWireType) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"messageWithWrongStringWireType"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + // The response is an invalid serialization of protobuf, so this should fail + ASSERT_EQ(-1, MozAgentInfo.client->Send(request, &response)); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageWithZeroTag) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"messageWithZeroTag"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + // The response is an invalid serialization of protobuf, so this should fail + ASSERT_EQ(-1, MozAgentInfo.client->Send(request, &response)); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageWithZeroFieldButNonzeroWireType) +{ + auto MozAgentInfo = + LaunchAgentMisbehaving(L"messageWithZeroFieldButNonzeroWireType"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + // The response is an invalid serialization of protobuf, so this should fail + ASSERT_EQ(-1, MozAgentInfo.client->Send(request, &response)); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageWithGroupEnd) +{ + auto MozAgentInfo = + LaunchAgentMisbehaving(L"messageWithZeroFieldButNonzeroWireType"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + // The response is an invalid serialization of protobuf, so this should fail + ASSERT_EQ(-1, MozAgentInfo.client->Send(request, &response)); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageTruncatedInMiddleOfVarint) +{ + auto MozAgentInfo = + LaunchAgentMisbehaving(L"messageTruncatedInMiddleOfVarint"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + // The response is an invalid serialization of protobuf, so this should fail + ASSERT_EQ(-1, MozAgentInfo.client->Send(request, &response)); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} + +TEST(ContentAnalysisMisbehaving, MessageTruncatedInMiddleOfTag) +{ + auto MozAgentInfo = LaunchAgentMisbehaving(L"messageTruncatedInMiddleOfTag"); + // Exit the test early if the process failed to launch + ASSERT_NE(MozAgentInfo.processInfo.dwProcessId, 0UL); + ASSERT_NE(nullptr, MozAgentInfo.client.get()); + + ContentAnalysisRequest request; + request.set_request_token("request token"); + ContentAnalysisResponse response; + // The response is an invalid serialization of protobuf, so this should fail + ASSERT_EQ(-1, MozAgentInfo.client->Send(request, &response)); + + BOOL terminateResult = + ::TerminateProcess(MozAgentInfo.processInfo.hProcess, 0); + ASSERT_NE(FALSE, terminateResult) + << "Failed to terminate content_analysis_sdk_agent process"; +} diff --git a/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysisUtils.cpp b/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysisUtils.cpp new file mode 100644 index 0000000000..fc0cca5acd --- /dev/null +++ b/toolkit/components/contentanalysis/tests/gtest/TestContentAnalysisUtils.cpp @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 https://mozilla.org/MPL/2.0/. */ + +#include "TestContentAnalysis.h" +#include +#include +#include +#include +#include + +void GeneratePipeName(const wchar_t* prefix, nsString& pipeName) { + pipeName = u""_ns; + pipeName.Append(prefix); + UUID uuid; + ASSERT_EQ(RPC_S_OK, UuidCreate(&uuid)); + // 39 == length of a UUID string including braces and NUL. + wchar_t guidBuf[39] = {}; + ASSERT_EQ(39, StringFromGUID2(uuid, guidBuf, 39)); + // omit opening and closing braces (and trailing null) + pipeName.Append(&guidBuf[1], 36); +} + +void LaunchAgentWithCommandLineArguments(const nsString& cmdLineArguments, + const nsString& pipeName, + MozAgentInfo& agentInfo) { + wchar_t progName[MAX_PATH] = {}; + // content_analysis_sdk_agent.exe is either next to firefox.exe (for local + // builds), or in ../../tests/bin/ (for try/treeherder builds) + DWORD nameSize = ::GetModuleFileNameW(nullptr, progName, MAX_PATH); + ASSERT_NE(DWORD{0}, nameSize); + ASSERT_EQ(S_OK, PathCchRemoveFileSpec(progName, nameSize)); + wchar_t normalizedPath[MAX_PATH] = {}; + nsString test1 = nsString(progName) + u"\\content_analysis_sdk_agent.exe"_ns; + ASSERT_EQ(S_OK, PathCchCanonicalize(normalizedPath, MAX_PATH, test1.get())); + nsString agentPath; + if (::PathFileExistsW(normalizedPath)) { + agentPath = nsString(normalizedPath); + } + if (agentPath.IsEmpty()) { + nsString unNormalizedPath = + nsString(progName) + + u"\\..\\..\\tests\\bin\\content_analysis_sdk_agent.exe"_ns; + ASSERT_EQ(S_OK, PathCchCanonicalize(normalizedPath, MAX_PATH, + unNormalizedPath.get())); + if (::PathFileExistsW(normalizedPath)) { + agentPath = nsString(normalizedPath); + } + } + ASSERT_FALSE(agentPath.IsEmpty()); + nsString localCmdLine = nsString(agentPath) + u" "_ns + cmdLineArguments; + STARTUPINFOW startupInfo = {sizeof(startupInfo)}; + PROCESS_INFORMATION processInfo; + BOOL ok = + ::CreateProcessW(nullptr, localCmdLine.get(), nullptr, nullptr, FALSE, 0, + nullptr, nullptr, &startupInfo, &processInfo); + // The documentation for CreateProcessW() says that any non-zero value is a + // success + if (!ok) { + // Show the last error + ASSERT_EQ(0UL, GetLastError()) + << "Failed to launch content_analysis_sdk_agent"; + } + // Allow time for the agent to set up the pipe + ::Sleep(2000); + content_analysis::sdk::Client::Config config; + config.name = NS_ConvertUTF16toUTF8(pipeName); + config.user_specific = true; + auto clientPtr = content_analysis::sdk::Client::Create(config); + ASSERT_NE(nullptr, clientPtr.get()); + + agentInfo.processInfo = processInfo; + agentInfo.client = std::move(clientPtr); +} diff --git a/toolkit/components/contentanalysis/tests/gtest/agent/moz.build b/toolkit/components/contentanalysis/tests/gtest/agent/moz.build new file mode 100644 index 0000000000..71a3a029ed --- /dev/null +++ b/toolkit/components/contentanalysis/tests/gtest/agent/moz.build @@ -0,0 +1,40 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +Program("content_analysis_sdk_agent") + +DEFINES["UNICODE"] = True +DEFINES["GOOGLE_PROTOBUF_NO_RTTI"] = True +DEFINES["GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER"] = True + +SOURCES += [ + "../../../../../../third_party/content_analysis_sdk/agent/src/agent_base.cc", + "../../../../../../third_party/content_analysis_sdk/agent/src/agent_utils_win.cc", + "../../../../../../third_party/content_analysis_sdk/agent/src/agent_win.cc", + "../../../../../../third_party/content_analysis_sdk/agent/src/event_base.cc", + "../../../../../../third_party/content_analysis_sdk/agent/src/event_win.cc", + "../../../../../../third_party/content_analysis_sdk/agent/src/scoped_print_handle_base.cc", + "../../../../../../third_party/content_analysis_sdk/agent/src/scoped_print_handle_win.cc", + "../../../../../../third_party/content_analysis_sdk/common/utils_win.cc", + "../../../../../../third_party/content_analysis_sdk/demo/agent.cc", + "../../../content_analysis/sdk/analysis.pb.cc", +] + +LOCAL_INCLUDES += [ + "../../../", + "../../../../../../third_party/content_analysis_sdk", + "../../../../../../third_party/content_analysis_sdk/agent/include/", +] + +USE_LIBS += [ + "mozglue", + "protobuf", + "zlib", +] + +OS_LIBS += [ + "advapi32", +] diff --git a/toolkit/components/contentanalysis/tests/gtest/allowedFile.txt b/toolkit/components/contentanalysis/tests/gtest/allowedFile.txt new file mode 100644 index 0000000000..1564d2d1bc --- /dev/null +++ b/toolkit/components/contentanalysis/tests/gtest/allowedFile.txt @@ -0,0 +1 @@ +allow me \ No newline at end of file diff --git a/toolkit/components/contentanalysis/tests/gtest/blockedFile.txt b/toolkit/components/contentanalysis/tests/gtest/blockedFile.txt new file mode 100644 index 0000000000..58d958775d --- /dev/null +++ b/toolkit/components/contentanalysis/tests/gtest/blockedFile.txt @@ -0,0 +1 @@ +block me \ No newline at end of file diff --git a/toolkit/components/contentanalysis/tests/gtest/moz.build b/toolkit/components/contentanalysis/tests/gtest/moz.build new file mode 100644 index 0000000000..ce701987a4 --- /dev/null +++ b/toolkit/components/contentanalysis/tests/gtest/moz.build @@ -0,0 +1,23 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +LOCAL_INCLUDES += [ + "../..", + "../../../../../third_party/content_analysis_sdk/browser/include/", +] + +if CONFIG["OS_TARGET"] == "WINNT": + UNIFIED_SOURCES += [ + "TestContentAnalysis.cpp", + "TestContentAnalysisMisbehaving.cpp", + "TestContentAnalysisUtils.cpp", + ] + DIRS += ["agent"] + OS_LIBS += ["pathcch"] + +TEST_HARNESS_FILES.gtest += ["allowedFile.txt", "blockedFile.txt"] + +FINAL_LIBRARY = "xul-gtest" -- cgit v1.2.3