Commit 21e07a5a authored by Joe Mason's avatar Joe Mason Committed by Commit Bot

Add typemaps for chrome_cleaner interfaces.

Bug: 830892
Change-Id: Ia87628d081cd11f415c56cd067237c4d6536b432
Reviewed-on: https://chromium-review.googlesource.com/1172733Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Reviewed-by: default avatarWill Harris <wfh@chromium.org>
Commit-Queue: Joe Mason <joenotcharles@chromium.org>
Cr-Commit-Position: refs/heads/master@{#587314}
parent 1b09a135
...@@ -32,6 +32,7 @@ test("chrome_cleaner_unittests") { ...@@ -32,6 +32,7 @@ test("chrome_cleaner_unittests") {
# Tests from sub-directories. # Tests from sub-directories.
"//chrome/chrome_cleaner/chrome_utils:unittest_sources", "//chrome/chrome_cleaner/chrome_utils:unittest_sources",
"//chrome/chrome_cleaner/http:unittest_sources", "//chrome/chrome_cleaner/http:unittest_sources",
"//chrome/chrome_cleaner/interfaces/typemaps:unittest_sources",
"//chrome/chrome_cleaner/ipc:unittest_sources", "//chrome/chrome_cleaner/ipc:unittest_sources",
"//chrome/chrome_cleaner/json_parser:unittest_sources", "//chrome/chrome_cleaner/json_parser:unittest_sources",
"//chrome/chrome_cleaner/logging:unittest_sources", "//chrome/chrome_cleaner/logging:unittest_sources",
......
...@@ -40,6 +40,19 @@ chrome_cleaner_mojom("json_parser_interface") { ...@@ -40,6 +40,19 @@ chrome_cleaner_mojom("json_parser_interface") {
] ]
} }
chrome_cleaner_mojom("engine_sandbox_test_interface") {
testonly = true
sources = [
"test_pup_typemap.mojom",
"test_string16_embedded_nulls.mojom",
]
deps = [
":engine_sandbox_interface",
]
}
chrome_cleaner_mojom("mojo_sandbox_hooks_test_interface") { chrome_cleaner_mojom("mojo_sandbox_hooks_test_interface") {
testonly = true testonly = true
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module chrome_cleaner.mojom;
import "chrome/chrome_cleaner/interfaces/pup.mojom";
// Simple interface that echoes the structs defined in this file for testing the
// corresponding typemaps.
interface TestPUPTypemap {
EchoRegKeyPath(RegKeyPath in_reg) => (RegKeyPath out_reg);
EchoRegistryFootprint(RegistryFootprint in_fp)
=> (RegistryFootprint out_fp);
EchoPUP(PUP in_pup) => (PUP out_pup);
};
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
module chrome_cleaner.mojom;
import "chrome/chrome_cleaner/interfaces/string16_embedded_nulls.mojom";
// Simple interface that echoes an object for typemap testing.
interface TestString16EmbeddedNulls {
Echo(String16EmbeddedNulls input) => (String16EmbeddedNulls output);
};
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
source_set("unittest_sources") {
testonly = true
sources = [
"pup_typemap_unittest.cc",
"string16_embedded_nulls_typemap_unittest.cc",
]
deps = [
"//chrome/chrome_cleaner/interfaces:engine_sandbox_interface",
"//chrome/chrome_cleaner/interfaces:engine_sandbox_test_interface",
"//chrome/chrome_cleaner/ipc:ipc_test_util",
"//chrome/chrome_cleaner/ipc:mojo_task_runner",
"//chrome/chrome_cleaner/strings",
"//chrome/chrome_cleaner/strings:string_test_helpers",
"//chrome/chrome_cleaner/test:test_util",
"//mojo/core/embedder:embedder",
"//testing/gtest",
]
}
include_rules = [
# Allow the typemaps to access their dependencies.
'+mojo/public/cpp/bindings',
'+mojo/public/cpp/base',
'+mojo/public/cpp/system/platform_handle.h',
# Allow unit tests to set up a mojo embedder.
'+mojo/core/embedder',
]
per-file *_mojom_traits*.*=set noparent
per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
per-file *_struct_traits*.*=set noparent
per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
per-file *.typemap=set noparent
per-file *.typemap=file://ipc/SECURITY_OWNERS
# Copyright 2018 Google Inc. All Rights Reserved.
mojom = "//chrome/chrome_cleaner/interfaces/pup.mojom"
public_headers = [
"//chrome/chrome_cleaner/os/registry.h",
"//chrome/chrome_cleaner/pup_data/pup_data.h",
]
public_deps = [
"//chrome/chrome_cleaner/os:common_os",
"//chrome/chrome_cleaner/proto:shared_pup_enums_proto",
"//chrome/chrome_cleaner/pup_data:pup_data_base",
"//chrome/chrome_cleaner/settings:settings",
"//mojo/public/cpp/bindings:struct_traits",
]
traits_headers =
[ "//chrome/chrome_cleaner/interfaces/typemaps/pup_struct_traits.h" ]
sources = [
"//chrome/chrome_cleaner/interfaces/typemaps/pup_struct_traits.cc",
]
type_mappings = [
"chrome_cleaner.mojom.RegKeyPath=chrome_cleaner::RegKeyPath",
"chrome_cleaner.mojom.RegistryFootprint=chrome_cleaner::PUPData::RegistryFootprint",
"chrome_cleaner.mojom.TraceLocation=chrome_cleaner::UwS::TraceLocation",
"chrome_cleaner.mojom.PUP=chrome_cleaner::PUPData::PUP",
]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/chrome_cleaner/interfaces/typemaps/pup_struct_traits.h"
#include "chrome/chrome_cleaner/interfaces/typemaps/string16_embedded_nulls_mojom_traits.h"
#include "chrome/chrome_cleaner/interfaces/typemaps/windows_handle_mojom_traits.h"
#include "chrome/chrome_cleaner/logging/proto/shared_data.pb.h"
#include "components/chrome_cleaner/public/typemaps/chrome_prompt_struct_traits.h"
#include "mojo/public/cpp/base/string16_mojom_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/cpp/system/platform_handle.h"
namespace mojo {
using chrome_cleaner::mojom::FileInfoDataView;
using chrome_cleaner::mojom::FilePathDataView;
using chrome_cleaner::mojom::PUPDataView;
using chrome_cleaner::mojom::TraceLocationDataView;
using chrome_cleaner::mojom::RegKeyPathDataView;
using chrome_cleaner::mojom::RegistryFootprintDataView;
using chrome_cleaner::FilePathSet;
using chrome_cleaner::PUPData;
using chrome_cleaner::RegKeyPath;
using chrome_cleaner::RegistryMatchRule;
using chrome_cleaner::String16EmbeddedNulls;
using chrome_cleaner::UnorderedFilePathSet;
using mojo_base::mojom::String16DataView;
namespace {
template <typename ValueDataView, typename Value>
bool ReadFromArrayDataView(ArrayDataView<ValueDataView>* array_view,
std::vector<Value>* out) {
for (size_t i = 0; i < array_view->size(); ++i) {
Value value;
if (!array_view->Read(i, &value))
return false;
out->push_back(value);
}
return true;
}
bool ReadFilePathSetFromArrayDataView(
ArrayDataView<FilePathDataView>* array_view,
FilePathSet* out) {
for (size_t i = 0; i < array_view->size(); ++i) {
base::FilePath file_path;
if (!array_view->Read(i, &file_path))
return false;
out->Insert(file_path);
}
return true;
}
} // namespace
// static
HANDLE
StructTraits<RegKeyPathDataView, RegKeyPath>::rootkey(
const RegKeyPath& reg_key_path) {
return reg_key_path.rootkey();
}
// static
base::string16 StructTraits<RegKeyPathDataView, RegKeyPath>::subkey(
const RegKeyPath& reg_key_path) {
return reg_key_path.subkey();
}
// static
chrome_cleaner::mojom::Wow64Access
StructTraits<RegKeyPathDataView, RegKeyPath>::wow64access(
const RegKeyPath& reg_key_path) {
return static_cast<chrome_cleaner::mojom::Wow64Access>(
reg_key_path.wow64access());
}
// static
bool StructTraits<RegKeyPathDataView, RegKeyPath>::Read(RegKeyPathDataView view,
RegKeyPath* out) {
HANDLE rootkey;
if (!view.ReadRootkey(&rootkey))
return false;
base::string16 subkey;
if (!view.ReadSubkey(&subkey))
return false;
const REGSAM wow64access = static_cast<REGSAM>(view.wow64access());
if (wow64access != KEY_WOW64_32KEY && wow64access != KEY_WOW64_64KEY &&
wow64access != 0) {
return false;
}
*out = RegKeyPath(HKEY_LOCAL_MACHINE, subkey, wow64access);
return true;
}
// static
RegKeyPath
StructTraits<RegistryFootprintDataView, PUPData::RegistryFootprint>::key_path(
const PUPData::RegistryFootprint& reg_footprint) {
return reg_footprint.key_path;
}
// static
String16EmbeddedNulls
StructTraits<RegistryFootprintDataView, PUPData::RegistryFootprint>::value_name(
const PUPData::RegistryFootprint& reg_footprint) {
return String16EmbeddedNulls(reg_footprint.value_name);
}
// static
String16EmbeddedNulls
StructTraits<RegistryFootprintDataView, PUPData::RegistryFootprint>::
value_substring(const PUPData::RegistryFootprint& reg_footprint) {
return String16EmbeddedNulls(reg_footprint.value_substring);
}
// static
uint32_t
StructTraits<RegistryFootprintDataView, PUPData::RegistryFootprint>::rule(
const PUPData::RegistryFootprint& reg_footprint) {
return static_cast<uint32_t>(reg_footprint.rule);
}
// static
bool StructTraits<RegistryFootprintDataView, PUPData::RegistryFootprint>::Read(
RegistryFootprintDataView view,
PUPData::RegistryFootprint* out) {
if (!view.ReadKeyPath(&out->key_path))
return false;
String16EmbeddedNulls value_name;
if (!view.ReadValueName(&value_name))
return false;
out->value_name = value_name.CastAsStringPiece16().as_string();
String16EmbeddedNulls value_substring;
if (!view.ReadValueSubstring(&value_substring))
return false;
out->value_substring = value_substring.CastAsStringPiece16().as_string();
if (!chrome_cleaner::RegistryMatchRule_IsValid(view.rule()))
return false;
out->rule = static_cast<RegistryMatchRule>(view.rule());
return true;
}
// static
int32_t StructTraits<chrome_cleaner::mojom::TraceLocationDataView,
chrome_cleaner::UwS::TraceLocation>::
value(const chrome_cleaner::UwS::TraceLocation& location) {
return static_cast<int32_t>(location);
}
// static
bool StructTraits<chrome_cleaner::mojom::TraceLocationDataView,
chrome_cleaner::UwS::TraceLocation>::
Read(chrome_cleaner::mojom::TraceLocationDataView view,
chrome_cleaner::UwS::TraceLocation* out) {
if (!chrome_cleaner::UwS::TraceLocation_IsValid(view.value()))
return false;
*out = static_cast<chrome_cleaner::UwS::TraceLocation>(view.value());
return true;
}
// static
const std::set<chrome_cleaner::UwS::TraceLocation>&
StructTraits<FileInfoDataView, PUPData::FileInfo>::found_in(
const PUPData::FileInfo& info) {
return info.found_in;
}
// static
bool StructTraits<FileInfoDataView, PUPData::FileInfo>::Read(
FileInfoDataView view,
PUPData::FileInfo* out) {
ArrayDataView<TraceLocationDataView> found_in_view;
view.GetFoundInDataView(&found_in_view);
for (size_t i = 0; i < found_in_view.size(); ++i) {
chrome_cleaner::UwS::TraceLocation location;
if (!found_in_view.Read(i, &location))
return false;
out->found_in.insert(location);
}
return true;
}
// static
const UnorderedFilePathSet&
StructTraits<PUPDataView, PUPData::PUP>::expanded_disk_footprints(
const PUPData::PUP& pup) {
return pup.expanded_disk_footprints.file_paths();
}
// static
const std::vector<PUPData::RegistryFootprint>&
StructTraits<PUPDataView, PUPData::PUP>::expanded_registry_footprints(
const PUPData::PUP& pup) {
return pup.expanded_registry_footprints;
}
// static
const std::vector<base::string16>&
StructTraits<PUPDataView, PUPData::PUP>::expanded_scheduled_tasks(
const PUPData::PUP& pup) {
return pup.expanded_scheduled_tasks;
}
// static
const PUPData::PUP::FileInfoMap::MapType&
StructTraits<PUPDataView, PUPData::PUP>::disk_footprints_info(
const chrome_cleaner::PUPData::PUP& pup) {
return pup.disk_footprints_info.map();
}
// static
bool StructTraits<PUPDataView, PUPData::PUP>::Read(PUPDataView view,
PUPData::PUP* out) {
ArrayDataView<FilePathDataView> disk_view;
view.GetExpandedDiskFootprintsDataView(&disk_view);
if (!ReadFilePathSetFromArrayDataView(&disk_view,
&out->expanded_disk_footprints)) {
return false;
}
ArrayDataView<RegistryFootprintDataView> reg_footprints_view;
view.GetExpandedRegistryFootprintsDataView(&reg_footprints_view);
if (!ReadFromArrayDataView(&reg_footprints_view,
&out->expanded_registry_footprints)) {
return false;
}
ArrayDataView<String16DataView> tasks_view;
view.GetExpandedScheduledTasksDataView(&tasks_view);
if (!ReadFromArrayDataView(&tasks_view, &out->expanded_scheduled_tasks)) {
return false;
}
MapDataView<FilePathDataView, FileInfoDataView> disk_footprints_info_view;
view.GetDiskFootprintsInfoDataView(&disk_footprints_info_view);
for (size_t i = 0; i < disk_footprints_info_view.size(); ++i) {
base::FilePath file_path;
PUPData::FileInfo file_info;
if (!disk_footprints_info_view.keys().Read(i, &file_path) ||
!disk_footprints_info_view.values().Read(i, &file_info))
return false;
out->disk_footprints_info.Insert(file_path, file_info);
}
return true;
}
} // namespace mojo
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_PUP_STRUCT_TRAITS_H_
#define CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_PUP_STRUCT_TRAITS_H_
#include <stdint.h>
#include "base/containers/span.h"
#include "base/strings/string16.h"
#include "chrome/chrome_cleaner/interfaces/pup.mojom.h"
#include "chrome/chrome_cleaner/interfaces/string16_embedded_nulls.mojom.h"
#include "chrome/chrome_cleaner/os/file_path_set.h"
#include "chrome/chrome_cleaner/os/registry.h"
#include "mojo/public/cpp/bindings/array_traits.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
namespace mojo {
template <>
struct StructTraits<chrome_cleaner::mojom::RegKeyPathDataView,
chrome_cleaner::RegKeyPath> {
static HANDLE rootkey(const chrome_cleaner::RegKeyPath& reg_key_path);
static base::string16 subkey(const chrome_cleaner::RegKeyPath& reg_key_path);
static chrome_cleaner::mojom::Wow64Access wow64access(
const chrome_cleaner::RegKeyPath& reg_key_path);
static bool Read(chrome_cleaner::mojom::RegKeyPathDataView view,
chrome_cleaner::RegKeyPath* out);
};
template <>
struct StructTraits<chrome_cleaner::mojom::RegistryFootprintDataView,
chrome_cleaner::PUPData::RegistryFootprint> {
static chrome_cleaner::RegKeyPath key_path(
const chrome_cleaner::PUPData::RegistryFootprint& reg_footprint);
static chrome_cleaner::String16EmbeddedNulls value_name(
const chrome_cleaner::PUPData::RegistryFootprint& reg_footprint);
static chrome_cleaner::String16EmbeddedNulls value_substring(
const chrome_cleaner::PUPData::RegistryFootprint& reg_footprint);
static uint32_t rule(
const chrome_cleaner::PUPData::RegistryFootprint& reg_footprint);
static bool Read(chrome_cleaner::mojom::RegistryFootprintDataView view,
chrome_cleaner::PUPData::RegistryFootprint* out);
};
template <>
struct StructTraits<chrome_cleaner::mojom::TraceLocationDataView,
chrome_cleaner::UwS::TraceLocation> {
static int32_t value(const chrome_cleaner::UwS::TraceLocation& location);
static bool Read(chrome_cleaner::mojom::TraceLocationDataView view,
chrome_cleaner::UwS::TraceLocation* out);
};
template <>
struct StructTraits<chrome_cleaner::mojom::FileInfoDataView,
chrome_cleaner::PUPData::FileInfo> {
static const std::set<chrome_cleaner::UwS::TraceLocation>& found_in(
const chrome_cleaner::PUPData::FileInfo& info);
static bool Read(chrome_cleaner::mojom::FileInfoDataView view,
chrome_cleaner::PUPData::FileInfo* out);
};
template <>
struct StructTraits<chrome_cleaner::mojom::PUPDataView,
chrome_cleaner::PUPData::PUP> {
// It's safe to return a reference, since the PUP object outlives the Mojo
// struct object.
static const chrome_cleaner::UnorderedFilePathSet& expanded_disk_footprints(
const chrome_cleaner::PUPData::PUP& pup);
// It's safe to return a reference, since the PUP object outlives the Mojo
// struct object.
static const std::vector<chrome_cleaner::PUPData::RegistryFootprint>&
expanded_registry_footprints(const chrome_cleaner::PUPData::PUP& pup);
// It's safe to return a reference, since the PUP object outlives the Mojo
// struct object.
static const std::vector<base::string16>& expanded_scheduled_tasks(
const chrome_cleaner::PUPData::PUP& pup);
static const chrome_cleaner::PUPData::PUP::FileInfoMap::MapType&
disk_footprints_info(const chrome_cleaner::PUPData::PUP& pup);
static bool Read(chrome_cleaner::mojom::PUPDataView view,
chrome_cleaner::PUPData::PUP* out);
};
} // namespace mojo
#endif // CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_PUP_STRUCT_TRAITS_H_
# Copyright 2018 Google Inc. All Rights Reserved.
mojom = "//chrome/chrome_cleaner/interfaces/string16_embedded_nulls.mojom"
public_headers = [ "//chrome/chrome_cleaner/strings/string16_embedded_nulls.h" ]
traits_headers = [ "//chrome/chrome_cleaner/interfaces/typemaps/string16_embedded_nulls_mojom_traits.h" ]
sources = [
"//chrome/chrome_cleaner/interfaces/typemaps/string16_embedded_nulls_mojom_traits.cc",
]
type_mappings = [ "chrome_cleaner.mojom.String16EmbeddedNulls=chrome_cleaner::String16EmbeddedNulls" ]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/chrome_cleaner/interfaces/typemaps/string16_embedded_nulls_mojom_traits.h"
namespace mojo {
using chrome_cleaner::mojom::NullValueDataView;
using chrome_cleaner::mojom::String16EmbeddedNullsDataView;
using chrome_cleaner::String16EmbeddedNulls;
// static
bool StructTraits<NullValueDataView, nullptr_t>::Read(NullValueDataView data,
nullptr_t* value) {
*value = nullptr;
return true;
}
// static
base::span<const uint16_t>
UnionTraits<String16EmbeddedNullsDataView, String16EmbeddedNulls>::value(
const String16EmbeddedNulls& str) {
DCHECK_EQ(String16EmbeddedNullsDataView::Tag::VALUE, GetTag(str));
// This should only be called by Mojo to get the data to be send through the
// pipe. When called by Mojo in this case, str will outlive the returned span.
return base::make_span(str.CastAsUInt16Array(), str.size());
}
// static
nullptr_t
UnionTraits<String16EmbeddedNullsDataView, String16EmbeddedNulls>::null_value(
const chrome_cleaner::String16EmbeddedNulls& str) {
DCHECK_EQ(String16EmbeddedNullsDataView::Tag::NULL_VALUE, GetTag(str));
return nullptr;
}
// static
chrome_cleaner::mojom::String16EmbeddedNullsDataView::Tag
UnionTraits<String16EmbeddedNullsDataView, String16EmbeddedNulls>::GetTag(
const chrome_cleaner::String16EmbeddedNulls& str) {
return str.size() == 0 ? String16EmbeddedNullsDataView::Tag::NULL_VALUE
: String16EmbeddedNullsDataView::Tag::VALUE;
}
// static
bool UnionTraits<String16EmbeddedNullsDataView, String16EmbeddedNulls>::Read(
String16EmbeddedNullsDataView str_view,
String16EmbeddedNulls* out) {
if (str_view.is_null_value()) {
*out = String16EmbeddedNulls();
return true;
}
ArrayDataView<uint16_t> view;
str_view.GetValueDataView(&view);
// Note: Casting is intentional, since the data view represents the string as
// a uint16_t array, whereas String16EmbeddedNulls's constructor expects
// a wchar_t array.
*out = String16EmbeddedNulls(reinterpret_cast<const wchar_t*>(view.data()),
view.size());
return true;
}
} // namespace mojo
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_STRING16_EMBEDDED_NULLS_MOJOM_TRAITS_H_
#define CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_STRING16_EMBEDDED_NULLS_MOJOM_TRAITS_H_
#include <stdint.h>
#include "base/containers/span.h"
#include "chrome/chrome_cleaner/interfaces//string16_embedded_nulls.mojom.h"
#include "chrome/chrome_cleaner/strings/string16_embedded_nulls.h"
#include "mojo/public/cpp/bindings/struct_traits.h"
#include "mojo/public/cpp/bindings/union_traits.h"
namespace mojo {
// Defines NullValue as mapped to nullptr_t.
template <>
struct StructTraits<chrome_cleaner::mojom::NullValueDataView, nullptr_t> {
static bool Read(chrome_cleaner::mojom::NullValueDataView data,
nullptr_t* value);
};
template <>
struct UnionTraits<chrome_cleaner::mojom::String16EmbeddedNullsDataView,
chrome_cleaner::String16EmbeddedNulls> {
// This should only be called by Mojo to marshal the object before sending it
// through the pipe.
static base::span<const uint16_t> value(
const chrome_cleaner::String16EmbeddedNulls& str);
static nullptr_t null_value(const chrome_cleaner::String16EmbeddedNulls& str);
static chrome_cleaner::mojom::String16EmbeddedNullsDataView::Tag GetTag(
const chrome_cleaner::String16EmbeddedNulls& str);
static bool Read(
chrome_cleaner::mojom::String16EmbeddedNullsDataView str_view,
chrome_cleaner::String16EmbeddedNulls* out);
};
} // namespace mojo
#endif // CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_STRING16_EMBEDDED_NULLS_MOJOM_TRAITS_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/synchronization/waitable_event.h"
#include "chrome/chrome_cleaner/interfaces/string16_embedded_nulls.mojom.h"
#include "chrome/chrome_cleaner/interfaces/test_string16_embedded_nulls.mojom.h"
#include "chrome/chrome_cleaner/ipc/ipc_test_util.h"
#include "chrome/chrome_cleaner/ipc/mojo_task_runner.h"
#include "chrome/chrome_cleaner/strings/string16_embedded_nulls.h"
#include "chrome/chrome_cleaner/strings/string_test_helpers.h"
#include "chrome/chrome_cleaner/test/test_util.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"
namespace chrome_cleaner {
namespace {
using base::WaitableEvent;
class TestString16EmbeddedNullsImpl : public mojom::TestString16EmbeddedNulls {
public:
explicit TestString16EmbeddedNullsImpl(
mojom::TestString16EmbeddedNullsRequest request)
: binding_(this, std::move(request)) {}
void Echo(const String16EmbeddedNulls& path, EchoCallback callback) override {
std::move(callback).Run(path);
}
private:
mojo::Binding<mojom::TestString16EmbeddedNulls> binding_;
};
class SandboxParentProcess : public chrome_cleaner::ParentProcess {
public:
explicit SandboxParentProcess(scoped_refptr<MojoTaskRunner> mojo_task_runner)
: ParentProcess(std::move(mojo_task_runner)) {}
protected:
void CreateImpl(mojo::ScopedMessagePipeHandle mojo_pipe) override {
mojom::TestString16EmbeddedNullsRequest request(std::move(mojo_pipe));
impl_ = std::make_unique<TestString16EmbeddedNullsImpl>(std::move(request));
}
void DestroyImpl() override { impl_.reset(); }
private:
~SandboxParentProcess() override = default;
std::unique_ptr<TestString16EmbeddedNullsImpl> impl_;
};
class SandboxChildProcess : public chrome_cleaner::ChildProcess {
public:
explicit SandboxChildProcess(scoped_refptr<MojoTaskRunner> mojo_task_runner)
: ChildProcess(mojo_task_runner),
ptr_(std::make_unique<mojom::TestString16EmbeddedNullsPtr>()) {}
void BindToPipe(mojo::ScopedMessagePipeHandle mojo_pipe,
WaitableEvent* event) {
ptr_->Bind(chrome_cleaner::mojom::TestString16EmbeddedNullsPtrInfo(
std::move(mojo_pipe), 0));
event->Signal();
}
bool SuccessfulEcho(const String16EmbeddedNulls& input) {
String16EmbeddedNulls output;
WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED);
mojo_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&SandboxChildProcess::RunEcho, base::Unretained(this),
input, GetSaveAndSignalCallback(&output, &event)));
event.Wait();
return input == output;
}
private:
~SandboxChildProcess() override {
mojo_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
[](std::unique_ptr<mojom::TestString16EmbeddedNullsPtr> ptr) {
ptr.reset();
},
base::Passed(&ptr_)));
}
template <typename EchoedType>
base::OnceCallback<void(const EchoedType&)> GetSaveAndSignalCallback(
EchoedType* output,
WaitableEvent* event) {
return base::BindOnce(
[](EchoedType* value_holder, WaitableEvent* event,
const EchoedType& value) {
*value_holder = value;
event->Signal();
},
output, event);
}
void RunEcho(const String16EmbeddedNulls& input,
mojom::TestString16EmbeddedNulls::EchoCallback callback) {
(*ptr_)->Echo(input, std::move(callback));
}
std::unique_ptr<mojom::TestString16EmbeddedNullsPtr> ptr_;
};
scoped_refptr<SandboxChildProcess> InitChildProcess() {
auto mojo_task_runner = MojoTaskRunner::Create();
auto child_process =
base::MakeRefCounted<SandboxChildProcess>(mojo_task_runner);
auto message_pipe_handle = child_process->CreateMessagePipeFromCommandLine();
WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
WaitableEvent::InitialState::NOT_SIGNALED);
mojo_task_runner->PostTask(
FROM_HERE, base::BindOnce(&SandboxChildProcess::BindToPipe, child_process,
base::Passed(&message_pipe_handle), &event));
event.Wait();
return child_process;
}
MULTIPROCESS_TEST_MAIN(EchoMain) {
scoped_refptr<SandboxChildProcess> child_process = InitChildProcess();
// Empty string.
EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls()));
EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(nullptr)));
EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(nullptr, 0)));
EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(nullptr, 1)));
EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(L"", 0)));
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(std::vector<wchar_t>{})));
EXPECT_TRUE(
child_process->SuccessfulEcho(String16EmbeddedNulls(base::string16())));
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(base::string16(L""))));
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(base::StringPiece16())));
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(base::StringPiece16(L""))));
// Null-terminated strings. Zeroes will be replaced with null characters.
constexpr wchar_t kStringWithNulls[] = L"string0with0nulls";
const std::vector<wchar_t> vec1 = CreateVectorWithNulls(kStringWithNulls);
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(vec1.data(), vec1.size())));
EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(vec1)));
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(base::string16(vec1.data(), vec1.size()))));
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(base::StringPiece16(vec1.data(), vec1.size()))));
// Non null-terminated strings.
const std::vector<wchar_t> vec2(vec1.begin(), vec1.end() - 1);
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(vec2.data(), vec2.size())));
EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(vec2)));
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(base::string16(vec2.data(), vec2.size()))));
EXPECT_TRUE(child_process->SuccessfulEcho(
String16EmbeddedNulls(base::StringPiece16(vec2.data(), vec2.size()))));
return ::testing::Test::HasNonfatalFailure();
}
class String16EmbeddedNullsTypemapTest : public ::testing::Test {
public:
void SetUp() override {
mojo_task_runner_ = MojoTaskRunner::Create();
parent_process_ =
base::MakeRefCounted<SandboxParentProcess>(mojo_task_runner_);
}
protected:
scoped_refptr<MojoTaskRunner> mojo_task_runner_;
scoped_refptr<SandboxParentProcess> parent_process_;
};
TEST_F(String16EmbeddedNullsTypemapTest, Echo) {
int32_t exit_code = -1;
EXPECT_TRUE(
parent_process_->LaunchConnectedChildProcess("EchoMain", &exit_code));
EXPECT_EQ(0, exit_code);
}
} // namespace
} // namespace chrome_cleaner
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
typemaps = [
"//chrome/chrome_cleaner/interfaces/typemaps/pup.typemap",
"//chrome/chrome_cleaner/interfaces/typemaps/string16_embedded_nulls.typemap",
"//chrome/chrome_cleaner/interfaces/typemaps/windows_handle.typemap",
]
# Copyright 2018 Google Inc. All Rights Reserved.
mojom = "//chrome/chrome_cleaner/interfaces/windows_handle.mojom"
public_headers = []
traits_headers = [
"//chrome/chrome_cleaner/interfaces/typemaps/windows_handle_mojom_traits.h",
]
sources = [
"//chrome/chrome_cleaner/interfaces/typemaps/windows_handle_mojom_traits.cc",
]
type_mappings =
[ "chrome_cleaner.mojom.WindowsHandle=HANDLE[copyable_pass_by_value]" ]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/chrome_cleaner/interfaces/typemaps/windows_handle_mojom_traits.h"
#include "mojo/public/cpp/system/platform_handle.h"
namespace mojo {
using chrome_cleaner::mojom::SpecialWindowsHandle;
using chrome_cleaner::mojom::WindowsHandleDataView;
namespace {
bool ToSpecialHandle(HANDLE handle, SpecialWindowsHandle* out_special_handle) {
DCHECK(out_special_handle);
if (handle == nullptr) {
*out_special_handle = SpecialWindowsHandle::NULL_HANDLE;
return true;
}
if (handle == INVALID_HANDLE_VALUE) {
*out_special_handle = SpecialWindowsHandle::INVALID_HANDLE;
return true;
}
if (handle == HKEY_CLASSES_ROOT) {
*out_special_handle = SpecialWindowsHandle::CLASSES_ROOT;
return true;
}
if (handle == HKEY_CURRENT_CONFIG) {
*out_special_handle = SpecialWindowsHandle::CURRENT_CONFIG;
return true;
}
if (handle == HKEY_CURRENT_USER) {
*out_special_handle = SpecialWindowsHandle::CURRENT_USER;
return true;
}
if (handle == HKEY_LOCAL_MACHINE) {
*out_special_handle = SpecialWindowsHandle::LOCAL_MACHINE;
return true;
}
if (handle == HKEY_USERS) {
*out_special_handle = SpecialWindowsHandle::USERS;
return true;
}
return false;
}
bool IsSpecialHandle(HANDLE handle) {
SpecialWindowsHandle unused;
return ToSpecialHandle(handle, &unused);
}
bool FromSpecialHandle(SpecialWindowsHandle special_handle,
HANDLE* out_handle) {
DCHECK(out_handle);
switch (special_handle) {
case SpecialWindowsHandle::NULL_HANDLE:
*out_handle = nullptr;
return true;
case SpecialWindowsHandle::INVALID_HANDLE:
*out_handle = INVALID_HANDLE_VALUE;
return true;
case SpecialWindowsHandle::CLASSES_ROOT:
*out_handle = HKEY_CLASSES_ROOT;
return true;
case SpecialWindowsHandle::CURRENT_CONFIG:
*out_handle = HKEY_CURRENT_CONFIG;
return true;
case SpecialWindowsHandle::CURRENT_USER:
*out_handle = HKEY_CURRENT_USER;
return true;
case SpecialWindowsHandle::LOCAL_MACHINE:
*out_handle = HKEY_LOCAL_MACHINE;
return true;
case SpecialWindowsHandle::USERS:
*out_handle = HKEY_USERS;
return true;
default:
return false;
}
}
// Duplicates a handle in the current process. Returns INVALID_HANDLE_VALUE on
// error.
HANDLE DuplicateWindowsHandle(HANDLE source_handle) {
const HANDLE current_process = ::GetCurrentProcess();
HANDLE new_handle = INVALID_HANDLE_VALUE;
if (::DuplicateHandle(current_process, source_handle, current_process,
&new_handle, 0, FALSE, DUPLICATE_SAME_ACCESS) == 0) {
PLOG(ERROR) << "Error duplicating handle " << source_handle;
return INVALID_HANDLE_VALUE;
}
return new_handle;
}
} // namespace
// static
mojo::ScopedHandle UnionTraits<WindowsHandleDataView, HANDLE>::raw_handle(
HANDLE handle) {
DCHECK_EQ(WindowsHandleDataView::Tag::RAW_HANDLE, GetTag(handle));
if (IsSpecialHandle(handle)) {
CHECK(false) << "Accessor raw_handle() should only be called when the "
"union's tag is RAW_HANDLE.";
return mojo::ScopedHandle();
}
HANDLE duplicate_handle = DuplicateWindowsHandle(handle);
return WrapPlatformFile(duplicate_handle);
}
// static
SpecialWindowsHandle UnionTraits<WindowsHandleDataView, HANDLE>::special_handle(
HANDLE handle) {
DCHECK_EQ(WindowsHandleDataView::Tag::SPECIAL_HANDLE, GetTag(handle));
SpecialWindowsHandle special_handle;
if (ToSpecialHandle(handle, &special_handle))
return special_handle;
CHECK(false) << "Accessor special_handle() should only be called when the "
"union's tag is SPECIAL_HANDLE.";
return SpecialWindowsHandle::INVALID_HANDLE;
}
// static
WindowsHandleDataView::Tag UnionTraits<WindowsHandleDataView, HANDLE>::GetTag(
HANDLE handle) {
return IsSpecialHandle(handle) ? WindowsHandleDataView::Tag::SPECIAL_HANDLE
: WindowsHandleDataView::Tag::RAW_HANDLE;
}
// static
bool UnionTraits<WindowsHandleDataView, HANDLE>::Read(
WindowsHandleDataView windows_handle_view,
HANDLE* out) {
if (windows_handle_view.is_raw_handle()) {
HANDLE handle;
MojoResult mojo_result =
UnwrapPlatformFile(windows_handle_view.TakeRawHandle(), &handle);
if (mojo_result != MOJO_RESULT_OK) {
*out = INVALID_HANDLE_VALUE;
return false;
}
*out = handle;
return true;
}
HANDLE special_handle;
if (FromSpecialHandle(windows_handle_view.special_handle(),
&special_handle)) {
*out = special_handle;
return true;
}
return false;
}
} // namespace mojo
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_WINDOWS_HANDLE_MOJOM_TRAITS_H_
#define CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_WINDOWS_HANDLE_MOJOM_TRAITS_H_
#include "chrome/chrome_cleaner/interfaces/windows_handle.mojom.h"
#include "mojo/public/cpp/bindings/union_traits.h"
namespace mojo {
template <>
struct UnionTraits<chrome_cleaner::mojom::WindowsHandleDataView, HANDLE> {
static mojo::ScopedHandle raw_handle(HANDLE handle);
static chrome_cleaner::mojom::SpecialWindowsHandle special_handle(
HANDLE handle);
static chrome_cleaner::mojom::WindowsHandleDataView::Tag GetTag(
HANDLE handle);
static bool Read(
chrome_cleaner::mojom::WindowsHandleDataView windows_handle_view,
HANDLE* out);
};
} // namespace mojo
#endif // CHROME_CHROME_CLEANER_INTERFACES_TYPEMAPS_WINDOWS_HANDLE_MOJOM_TRAITS_H_
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
_typemap_imports = [ _typemap_imports = [
"//ash/public/interfaces/typemaps.gni", "//ash/public/interfaces/typemaps.gni",
"//chrome/chrome_cleaner/interfaces/typemaps/typemaps.gni",
"//chrome/common/extensions/typemaps.gni", "//chrome/common/extensions/typemaps.gni",
"//chrome/common/importer/typemaps.gni", "//chrome/common/importer/typemaps.gni",
"//chrome/common/media_router/mojo/typemaps.gni", "//chrome/common/media_router/mojo/typemaps.gni",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment