summaryrefslogtreecommitdiff
path: root/chromium/services/data_decoder
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/services/data_decoder
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
downloadqtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/services/data_decoder')
-rw-r--r--chromium/services/data_decoder/BUILD.gn26
-rw-r--r--chromium/services/data_decoder/data_decoder_service.cc11
-rw-r--r--chromium/services/data_decoder/data_decoder_service.h13
-rw-r--r--chromium/services/data_decoder/image_decoder_impl.cc18
-rw-r--r--chromium/services/data_decoder/image_decoder_impl_unittest.cc2
-rw-r--r--chromium/services/data_decoder/public/cpp/BUILD.gn21
-rw-r--r--chromium/services/data_decoder/public/cpp/android/BUILD.gn2
-rw-r--r--chromium/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java16
-rw-r--r--chromium/services/data_decoder/public/cpp/data_decoder.cc3
-rw-r--r--chromium/services/data_decoder/public/cpp/decode_image.cc5
-rw-r--r--chromium/services/data_decoder/public/cpp/json_sanitizer_android.cc2
-rw-r--r--chromium/services/data_decoder/public/cpp/json_sanitizer_unittest.cc44
-rw-r--r--chromium/services/data_decoder/public/cpp/safe_web_bundle_parser_unittest.cc7
-rw-r--r--chromium/services/data_decoder/public/cpp/test_support/web_bundle_builder.cc149
-rw-r--r--chromium/services/data_decoder/public/cpp/test_support/web_bundle_builder.h80
-rw-r--r--chromium/services/data_decoder/public/mojom/BUILD.gn19
-rw-r--r--chromium/services/data_decoder/public/mojom/constants.mojom7
-rw-r--r--chromium/services/data_decoder/public/mojom/data_decoder_service.mojom4
-rw-r--r--chromium/services/data_decoder/public/mojom/image_decoder.mojom1
-rw-r--r--chromium/services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom26
-rw-r--r--chromium/services/data_decoder/public/mojom/web_bundle_parser.mojom3
-rw-r--r--chromium/services/data_decoder/public/mojom/web_bundler.mojom24
-rw-r--r--chromium/services/data_decoder/web_bundle_parser.cc52
-rw-r--r--chromium/services/data_decoder/web_bundle_parser.h1
-rw-r--r--chromium/services/data_decoder/web_bundle_parser_factory.cc14
-rw-r--r--chromium/services/data_decoder/web_bundle_parser_factory_unittest.cc41
-rw-r--r--chromium/services/data_decoder/web_bundle_parser_fuzzer.cc20
-rw-r--r--chromium/services/data_decoder/web_bundle_parser_unittest.cc226
-rw-r--r--chromium/services/data_decoder/web_bundler.cc19
-rw-r--r--chromium/services/data_decoder/web_bundler.h37
-rw-r--r--chromium/services/data_decoder/xml_parser_fuzzer.cc4
-rw-r--r--chromium/services/data_decoder/xml_parser_unittest.cc3
32 files changed, 543 insertions, 357 deletions
diff --git a/chromium/services/data_decoder/BUILD.gn b/chromium/services/data_decoder/BUILD.gn
index c59d28d13c1..fa455db7aa3 100644
--- a/chromium/services/data_decoder/BUILD.gn
+++ b/chromium/services/data_decoder/BUILD.gn
@@ -14,6 +14,8 @@ source_set("lib") {
"web_bundle_parser.h",
"web_bundle_parser_factory.cc",
"web_bundle_parser_factory.h",
+ "web_bundler.cc",
+ "web_bundler.h",
"xml_parser.cc",
"xml_parser.h",
]
@@ -38,9 +40,7 @@ source_set("lib") {
"//ui/gfx/geometry",
]
- public_deps = [
- "//services/data_decoder/public/mojom",
- ]
+ public_deps = [ "//services/data_decoder/public/mojom" ]
if (!is_ios) {
sources += [
@@ -88,9 +88,7 @@ source_set("tests") {
"//gin:gin_test",
"//third_party/blink/public:blink",
]
- data_deps = [
- "//tools/v8_context_snapshot",
- ]
+ data_deps = [ "//tools/v8_context_snapshot" ]
configs += [
"//tools/v8_context_snapshot:use_v8_context_snapshot",
"//v8:external_startup_data",
@@ -99,9 +97,7 @@ source_set("tests") {
}
fuzzer_test("web_bundle_parser_fuzzer") {
- sources = [
- "web_bundle_parser_fuzzer.cc",
- ]
+ sources = [ "web_bundle_parser_fuzzer.cc" ]
deps = [
":lib",
"//base",
@@ -111,9 +107,7 @@ fuzzer_test("web_bundle_parser_fuzzer") {
}
fuzzer_test("xml_parser_fuzzer") {
- sources = [
- "xml_parser_fuzzer.cc",
- ]
+ sources = [ "xml_parser_fuzzer.cc" ]
deps = [
":lib",
"//base",
@@ -126,11 +120,7 @@ fuzzer_test("xml_parser_fuzzer") {
if (is_chromeos) {
fuzzer_test("ble_scan_parser_fuzzer") {
- sources = [
- "ble_scan_parser_impl_fuzzer.cc",
- ]
- deps = [
- ":lib",
- ]
+ sources = [ "ble_scan_parser_impl_fuzzer.cc" ]
+ deps = [ ":lib" ]
}
}
diff --git a/chromium/services/data_decoder/data_decoder_service.cc b/chromium/services/data_decoder/data_decoder_service.cc
index 837a7c5d254..f841ce45bfa 100644
--- a/chromium/services/data_decoder/data_decoder_service.cc
+++ b/chromium/services/data_decoder/data_decoder_service.cc
@@ -16,6 +16,7 @@
#include "services/data_decoder/json_parser_impl.h"
#include "services/data_decoder/public/mojom/image_decoder.mojom.h"
#include "services/data_decoder/web_bundle_parser_factory.h"
+#include "services/data_decoder/web_bundler.h"
#include "services/data_decoder/xml_parser.h"
#if defined(OS_CHROMEOS)
@@ -78,6 +79,16 @@ void DataDecoderService::BindWebBundleParserFactory(
}
}
+void DataDecoderService::BindWebBundler(
+ mojo::PendingReceiver<mojom::WebBundler> receiver) {
+ if (web_bundler_binder_) {
+ web_bundler_binder_.Run(std::move(receiver));
+ } else {
+ mojo::MakeSelfOwnedReceiver(std::make_unique<WebBundler>(),
+ std::move(receiver));
+ }
+}
+
#ifdef OS_CHROMEOS
void DataDecoderService::BindBleScanParser(
mojo::PendingReceiver<mojom::BleScanParser> receiver) {
diff --git a/chromium/services/data_decoder/data_decoder_service.h b/chromium/services/data_decoder/data_decoder_service.h
index dd7349588f7..b3999002ffe 100644
--- a/chromium/services/data_decoder/data_decoder_service.h
+++ b/chromium/services/data_decoder/data_decoder_service.h
@@ -14,6 +14,7 @@
#include "services/data_decoder/public/mojom/image_decoder.mojom.h"
#include "services/data_decoder/public/mojom/json_parser.mojom.h"
#include "services/data_decoder/public/mojom/web_bundle_parser.mojom.h"
+#include "services/data_decoder/public/mojom/web_bundler.mojom.h"
#include "services/data_decoder/public/mojom/xml_parser.mojom.h"
#ifdef OS_CHROMEOS
@@ -54,6 +55,14 @@ class DataDecoderService : public mojom::DataDecoderService {
web_bundle_parser_factory_binder_ = binder;
}
+ // Configures the service to use |binder| to bind WebBundler in subsequent
+ // BindWebBundler() calls.
+ void SetWebBundlerBinderForTesting(
+ base::RepeatingCallback<void(mojo::PendingReceiver<mojom::WebBundler>)>
+ binder) {
+ web_bundler_binder_ = binder;
+ }
+
private:
// mojom::DataDecoderService implementation:
void BindImageDecoder(
@@ -63,6 +72,8 @@ class DataDecoderService : public mojom::DataDecoderService {
void BindXmlParser(mojo::PendingReceiver<mojom::XmlParser> receiver) override;
void BindWebBundleParserFactory(
mojo::PendingReceiver<mojom::WebBundleParserFactory> receiver) override;
+ void BindWebBundler(
+ mojo::PendingReceiver<mojom::WebBundler> receiver) override;
#ifdef OS_CHROMEOS
void BindBleScanParser(
@@ -78,6 +89,8 @@ class DataDecoderService : public mojom::DataDecoderService {
base::RepeatingCallback<void(
mojo::PendingReceiver<mojom::WebBundleParserFactory>)>
web_bundle_parser_factory_binder_;
+ base::RepeatingCallback<void(mojo::PendingReceiver<mojom::WebBundler>)>
+ web_bundler_binder_;
DISALLOW_COPY_AND_ASSIGN(DataDecoderService);
};
diff --git a/chromium/services/data_decoder/image_decoder_impl.cc b/chromium/services/data_decoder/image_decoder_impl.cc
index b19e57ca96e..e65dc0d2c97 100644
--- a/chromium/services/data_decoder/image_decoder_impl.cc
+++ b/chromium/services/data_decoder/image_decoder_impl.cc
@@ -17,7 +17,6 @@
#include "third_party/skia/include/core/SkBitmap.h"
#if defined(OS_CHROMEOS)
-#include "ui/gfx/codec/chromeos/jpeg_codec_robust_slow.h"
#include "ui/gfx/codec/png_codec.h"
#endif
@@ -25,13 +24,6 @@ namespace data_decoder {
namespace {
-#if defined(OS_CHROMEOS)
-// NOTE: This 1 GB limit is arbitrary and may be subject to change. The purpose
-// of limiting image decode size is to avoid OOM crashes caused by very large
-// image data being thrown at the service.
-constexpr size_t kJpegMaxDecodedNumBytes = 1024 * 1024 * 1024;
-#endif
-
int64_t kPadding = 64;
void ResizeImage(SkBitmap* decoded_image,
@@ -82,15 +74,7 @@ void ImageDecoderImpl::DecodeImage(const std::vector<uint8_t>& encoded_data,
SkBitmap decoded_image;
#if defined(OS_CHROMEOS)
- if (codec == mojom::ImageCodec::ROBUST_JPEG) {
- // Our robust jpeg decoding is using IJG libjpeg.
- if (encoded_data.size()) {
- std::unique_ptr<SkBitmap> decoded_jpeg(gfx::JPEGCodecRobustSlow::Decode(
- encoded_data, kJpegMaxDecodedNumBytes));
- if (decoded_jpeg.get() && !decoded_jpeg->empty())
- decoded_image = *decoded_jpeg;
- }
- } else if (codec == mojom::ImageCodec::ROBUST_PNG) {
+ if (codec == mojom::ImageCodec::ROBUST_PNG) {
// Our robust PNG decoding is using libpng.
if (encoded_data.size()) {
SkBitmap decoded_png;
diff --git a/chromium/services/data_decoder/image_decoder_impl_unittest.cc b/chromium/services/data_decoder/image_decoder_impl_unittest.cc
index 08669eed733..ffa4445b51d 100644
--- a/chromium/services/data_decoder/image_decoder_impl_unittest.cc
+++ b/chromium/services/data_decoder/image_decoder_impl_unittest.cc
@@ -62,7 +62,7 @@ class Request {
decoder_->DecodeImage(
image, mojom::ImageCodec::DEFAULT, shrink, kTestMaxImageSize,
gfx::Size(), // Take the smallest frame (there's only one frame).
- base::Bind(&Request::OnRequestDone, base::Unretained(this)));
+ base::BindOnce(&Request::OnRequestDone, base::Unretained(this)));
}
const SkBitmap& bitmap() const { return bitmap_; }
diff --git a/chromium/services/data_decoder/public/cpp/BUILD.gn b/chromium/services/data_decoder/public/cpp/BUILD.gn
index a2e051577f1..4dd89896df9 100644
--- a/chromium/services/data_decoder/public/cpp/BUILD.gn
+++ b/chromium/services/data_decoder/public/cpp/BUILD.gn
@@ -8,13 +8,9 @@ import("//mojo/public/tools/bindings/mojom.gni")
# converted to a component target. A component target is necessary for
# ServiceProvider because it exposes global storage.
component("service_provider") {
- public = [
- "service_provider.h",
- ]
+ public = [ "service_provider.h" ]
- sources = [
- "service_provider.cc",
- ]
+ sources = [ "service_provider.cc" ]
public_deps = [
"//base",
@@ -51,9 +47,8 @@ source_set("cpp") {
if (is_android) {
sources += [ "json_sanitizer_android.cc" ]
- deps = [
- "//services/data_decoder/public/cpp/android:safe_json_jni_headers",
- ]
+ deps =
+ [ "//services/data_decoder/public/cpp/android:safe_json_jni_headers" ]
} else {
sources += [ "json_sanitizer_non_android.cc" ]
}
@@ -62,9 +57,7 @@ source_set("cpp") {
# NOTE: We depend on this target here for iOS only, to support in-process
# use of the service. Non-test targets in this directory should otherwise
# NEVER depend on this target.
- deps = [
- "//services/data_decoder:lib",
- ]
+ deps = [ "//services/data_decoder:lib" ]
} else {
public += [
"decode_image.h",
@@ -84,8 +77,12 @@ source_set("test_support") {
sources = [
"test_support/in_process_data_decoder.cc",
"test_support/in_process_data_decoder.h",
+ "test_support/web_bundle_builder.cc",
+ "test_support/web_bundle_builder.h",
]
+ deps = [ "//components/cbor" ]
+
public_deps = [
":cpp",
"//base",
diff --git a/chromium/services/data_decoder/public/cpp/android/BUILD.gn b/chromium/services/data_decoder/public/cpp/android/BUILD.gn
index 8db1e96c850..266012dba9f 100644
--- a/chromium/services/data_decoder/public/cpp/android/BUILD.gn
+++ b/chromium/services/data_decoder/public/cpp/android/BUILD.gn
@@ -18,6 +18,6 @@ if (current_toolchain == default_toolchain) {
"//base:jni_java",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
- java_files = [] + _jni_sources
+ sources = [] + _jni_sources
}
}
diff --git a/chromium/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java b/chromium/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java
index f398f4115d3..868cb60c850 100644
--- a/chromium/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java
+++ b/chromium/services/data_decoder/public/cpp/android/java/src/org/chromium/services/data_decoder/JsonSanitizer.java
@@ -148,7 +148,7 @@ public class JsonSanitizer {
/**
* Checks whether a given String is well-formed UTF-16, i.e. all surrogates appear in high-low
- * pairs and each code point is a valid character.
+ * pairs, in other words: each character is a valid Unicode code point.
*
* @param string The string to check.
* @return Whether the given string is well-formed UTF-16.
@@ -159,7 +159,7 @@ public class JsonSanitizer {
char c = string.charAt(i);
// Check that surrogates only appear in pairs of a high surrogate followed by a low
// surrogate.
- // A lone low surrogate is not allowed.
+ // A lone surrogate is not allowed.
if (Character.isLowSurrogate(c)) return false;
int codePoint;
@@ -174,22 +174,14 @@ public class JsonSanitizer {
// Decode the high-low pair into a code point.
codePoint = Character.toCodePoint(high, low);
} else {
- // The code point is neither a low surrogate nor a high surrogate, so we just need
- // to check that it's a valid character.
+ // The code point is neither a low surrogate nor a high surrogate, so
+ // it's a valid Unicode character.
codePoint = c;
}
-
- if (!isUnicodeCharacter(codePoint)) return false;
}
return true;
}
- private static boolean isUnicodeCharacter(int codePoint) {
- // See the native method base::IsValidCharacter().
- return codePoint < 0xD800 || (codePoint >= 0xE000 && codePoint < 0xFDD0)
- || (codePoint > 0xFDEF && codePoint <= 0x10FFFF && (codePoint & 0xFFFE) != 0xFFFE);
- }
-
@NativeMethods
interface Natives {
void onSuccess(long id, String json);
diff --git a/chromium/services/data_decoder/public/cpp/data_decoder.cc b/chromium/services/data_decoder/public/cpp/data_decoder.cc
index 9ba33ff47e2..29ad02fe4c7 100644
--- a/chromium/services/data_decoder/public/cpp/data_decoder.cc
+++ b/chromium/services/data_decoder/public/cpp/data_decoder.cc
@@ -6,6 +6,7 @@
#include "base/memory/ref_counted.h"
#include "base/no_destructor.h"
+#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "services/data_decoder/public/mojom/json_parser.mojom.h"
@@ -105,7 +106,7 @@ class ValueParseRequest : public base::RefCounted<ValueParseRequest<T>> {
void BindInProcessService(
mojo::PendingReceiver<mojom::DataDecoderService> receiver) {
static base::NoDestructor<scoped_refptr<base::SequencedTaskRunner>>
- task_runner{base::CreateSequencedTaskRunner({base::ThreadPool()})};
+ task_runner{base::ThreadPool::CreateSequencedTaskRunner({})};
if (!(*task_runner)->RunsTasksInCurrentSequence()) {
(*task_runner)
->PostTask(FROM_HERE,
diff --git a/chromium/services/data_decoder/public/cpp/decode_image.cc b/chromium/services/data_decoder/public/cpp/decode_image.cc
index 5707600c8c4..b395086b35f 100644
--- a/chromium/services/data_decoder/public/cpp/decode_image.cc
+++ b/chromium/services/data_decoder/public/cpp/decode_image.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "third_party/skia/include/core/SkBitmap.h"
@@ -104,8 +105,8 @@ void DecodeAnimation(DataDecoder* data_decoder,
// |call_once| runs |callback| on its first invocation.
auto call_once = base::AdaptCallbackForRepeating(std::move(callback));
- decoder.set_disconnect_handler(base::BindOnce(
- call_once, base::Passed(std::vector<mojom::AnimationFramePtr>())));
+ decoder.set_disconnect_handler(
+ base::BindOnce(call_once, std::vector<mojom::AnimationFramePtr>()));
mojom::ImageDecoder* raw_decoder = decoder.get();
raw_decoder->DecodeAnimation(
diff --git a/chromium/services/data_decoder/public/cpp/json_sanitizer_android.cc b/chromium/services/data_decoder/public/cpp/json_sanitizer_android.cc
index 5ed2b7aed63..b4e7efb1ba5 100644
--- a/chromium/services/data_decoder/public/cpp/json_sanitizer_android.cc
+++ b/chromium/services/data_decoder/public/cpp/json_sanitizer_android.cc
@@ -35,7 +35,7 @@ namespace data_decoder {
// static
void JsonSanitizer::Sanitize(const std::string& json, Callback callback) {
// The JSON parser only accepts wellformed UTF-8.
- if (!base::IsStringUTF8(json)) {
+ if (!base::IsStringUTF8AllowingNoncharacters(json)) {
base::SequencedTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback),
Result::Error("Unsupported encoding")));
diff --git a/chromium/services/data_decoder/public/cpp/json_sanitizer_unittest.cc b/chromium/services/data_decoder/public/cpp/json_sanitizer_unittest.cc
index b3d53dc38de..cbc0d7da423 100644
--- a/chromium/services/data_decoder/public/cpp/json_sanitizer_unittest.cc
+++ b/chromium/services/data_decoder/public/cpp/json_sanitizer_unittest.cc
@@ -46,7 +46,7 @@ void CheckSuccess(const std::string& json) {
EXPECT_TRUE(result_received);
}
-// Verifies that |json| is rejected by the sanitizer as an invlid string.
+// Verifies that |json| is rejected by the sanitizer as an invalid string.
void CheckError(const std::string& json) {
base::RunLoop loop;
bool result_received = false;
@@ -135,10 +135,44 @@ TEST_F(DataDecoderJsonSanitizerTest, Unicode) {
// A low surrogate followed by a high surrogate.
CheckError("[\"\\ude03\\ud83d\"]");
- // Valid escaped UTF-16 that encodes non-characters:
- CheckError("[\"\\ufdd0\"]");
- CheckError("[\"\\ufffe\"]");
- CheckError("[\"\\ud83f\\udffe\"]");
+ // Valid escaped UTF-16 that encodes non-characters.
+ CheckSuccess("[\"\\uFDD0\"]"); // U+FDD0
+ CheckSuccess("[\"\\uFDDF\"]"); // U+FDDF
+ CheckSuccess("[\"\\uFDEF\"]"); // U+FDEF
+ CheckSuccess("[\"\\uFFFE\"]"); // U+FFFE
+ CheckSuccess("[\"\\uFFFF\"]"); // U+FFFF
+ CheckSuccess("[\"\\uD83F\\uDFFE\"]"); // U+01FFFE
+ CheckSuccess("[\"\\uD83F\\uDFFF\"]"); // U+01FFFF
+ CheckSuccess("[\"\\uD87F\\uDFFE\"]"); // U+02FFFE
+ CheckSuccess("[\"\\uD87F\\uDFFF\"]"); // U+02FFFF
+ CheckSuccess("[\"\\uD8BF\\uDFFE\"]"); // U+03FFFE
+ CheckSuccess("[\"\\uD8BF\\uDFFF\"]"); // U+03FFFF
+ CheckSuccess("[\"\\uD8FF\\uDFFE\"]"); // U+04FFFE
+ CheckSuccess("[\"\\uD8FF\\uDFFF\"]"); // U+04FFFF
+ CheckSuccess("[\"\\uD93F\\uDFFE\"]"); // U+05FFFE
+ CheckSuccess("[\"\\uD93F\\uDFFF\"]"); // U+05FFFF
+ CheckSuccess("[\"\\uD97F\\uDFFE\"]"); // U+06FFFE
+ CheckSuccess("[\"\\uD97F\\uDFFF\"]"); // U+06FFFF
+ CheckSuccess("[\"\\uD9BF\\uDFFE\"]"); // U+07FFFE
+ CheckSuccess("[\"\\uD9BF\\uDFFF\"]"); // U+07FFFF
+ CheckSuccess("[\"\\uD9FF\\uDFFE\"]"); // U+08FFFE
+ CheckSuccess("[\"\\uD9FF\\uDFFF\"]"); // U+08FFFF
+ CheckSuccess("[\"\\uDA3F\\uDFFE\"]"); // U+09FFFE
+ CheckSuccess("[\"\\uDA3F\\uDFFF\"]"); // U+09FFFF
+ CheckSuccess("[\"\\uDA7F\\uDFFE\"]"); // U+0AFFFE
+ CheckSuccess("[\"\\uDA7F\\uDFFF\"]"); // U+0AFFFF
+ CheckSuccess("[\"\\uDABF\\uDFFE\"]"); // U+0BFFFE
+ CheckSuccess("[\"\\uDABF\\uDFFF\"]"); // U+0BFFFF
+ CheckSuccess("[\"\\uDAFF\\uDFFE\"]"); // U+0CFFFE
+ CheckSuccess("[\"\\uDAFF\\uDFFF\"]"); // U+0CFFFF
+ CheckSuccess("[\"\\uDB3F\\uDFFE\"]"); // U+0DFFFE
+ CheckSuccess("[\"\\uDB3F\\uDFFF\"]"); // U+0DFFFF
+ CheckSuccess("[\"\\uDB7F\\uDFFE\"]"); // U+0EFFFE
+ CheckSuccess("[\"\\uDB7F\\uDFFF\"]"); // U+0EFFFF
+ CheckSuccess("[\"\\uDBBF\\uDFFE\"]"); // U+0FFFFE
+ CheckSuccess("[\"\\uDBBF\\uDFFF\"]"); // U+0FFFFF
+ CheckSuccess("[\"\\uDBFF\\uDFFE\"]"); // U+10FFFE
+ CheckSuccess("[\"\\uDBFF\\uDFFF\"]"); // U+10FFFF
}
} // namespace
diff --git a/chromium/services/data_decoder/public/cpp/safe_web_bundle_parser_unittest.cc b/chromium/services/data_decoder/public/cpp/safe_web_bundle_parser_unittest.cc
index f82ddc7dd5a..8709166d18b 100644
--- a/chromium/services/data_decoder/public/cpp/safe_web_bundle_parser_unittest.cc
+++ b/chromium/services/data_decoder/public/cpp/safe_web_bundle_parser_unittest.cc
@@ -101,7 +101,6 @@ class MockDataSource final : public mojom::BundleDataSource {
private:
// Implements mojom::BundledDataSource.
- void GetSize(GetSizeCallback callback) override {}
void Read(uint64_t offset, uint64_t length, ReadCallback callback) override {}
mojo::Receiver<mojom::BundleDataSource> receiver_;
@@ -140,7 +139,7 @@ TEST_F(SafeWebBundleParserTest, ParseGoldenFile) {
{
base::RunLoop run_loop;
parser.ParseMetadata(base::BindOnce(
- [](base::Closure quit_closure,
+ [](base::OnceClosure quit_closure,
mojom::BundleMetadataPtr* metadata_result,
mojom::BundleMetadataPtr metadata,
mojom::BundleMetadataParseErrorPtr error) {
@@ -164,7 +163,7 @@ TEST_F(SafeWebBundleParserTest, ParseGoldenFile) {
entry.second->response_locations[0]->offset,
entry.second->response_locations[0]->length,
base::BindOnce(
- [](base::Closure quit_closure, const std::string url,
+ [](base::OnceClosure quit_closure, const std::string url,
std::map<std::string, mojom::BundleResponsePtr>* responses,
mojom::BundleResponsePtr response,
mojom::BundleResponseParseErrorPtr error) {
@@ -260,7 +259,7 @@ TEST_F(SafeWebBundleParserTest, ConnectionError) {
base::RunLoop run_loop;
bool parsed = false;
parser.ParseMetadata(base::BindOnce(
- [](base::Closure quit_closure, bool* parsed,
+ [](base::OnceClosure quit_closure, bool* parsed,
mojom::BundleMetadataPtr metadata,
mojom::BundleMetadataParseErrorPtr error) {
EXPECT_FALSE(metadata);
diff --git a/chromium/services/data_decoder/public/cpp/test_support/web_bundle_builder.cc b/chromium/services/data_decoder/public/cpp/test_support/web_bundle_builder.cc
new file mode 100644
index 00000000000..8155e97d512
--- /dev/null
+++ b/chromium/services/data_decoder/public/cpp/test_support/web_bundle_builder.cc
@@ -0,0 +1,149 @@
+// Copyright 2020 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 "services/data_decoder/public/cpp/test_support/web_bundle_builder.h"
+
+namespace data_decoder {
+namespace test {
+
+namespace {
+
+cbor::Value CreateByteString(base::StringPiece s) {
+ return cbor::Value(base::as_bytes(base::make_span(s)));
+}
+
+cbor::Value CreateHeaderMap(const WebBundleBuilder::Headers& headers) {
+ cbor::Value::MapValue map;
+ for (const auto& pair : headers)
+ map.insert({CreateByteString(pair.first), CreateByteString(pair.second)});
+ return cbor::Value(std::move(map));
+}
+
+} // namespace
+
+WebBundleBuilder::WebBundleBuilder(const std::string& fallback_url,
+ const std::string& manifest_url)
+ : fallback_url_(fallback_url) {
+ writer_config_.allow_invalid_utf8_for_testing = true;
+ if (!manifest_url.empty()) {
+ AddSection("manifest",
+ cbor::Value::InvalidUTF8StringValueForTesting(manifest_url));
+ }
+}
+
+WebBundleBuilder::~WebBundleBuilder() = default;
+
+void WebBundleBuilder::AddExchange(base::StringPiece url,
+ const Headers& response_headers,
+ base::StringPiece payload) {
+ AddIndexEntry(url, "", {AddResponse(response_headers, payload)});
+}
+
+WebBundleBuilder::ResponseLocation WebBundleBuilder::AddResponse(
+ const Headers& headers,
+ base::StringPiece payload) {
+ // We assume that the size of the CBOR header of the responses array is 1,
+ // which is true only if the responses array has no more than 23 elements.
+ DCHECK_LT(responses_.size(), 23u)
+ << "WebBundleBuilder cannot create bundles with more than 23 responses";
+
+ cbor::Value::ArrayValue response_array;
+ response_array.emplace_back(Encode(CreateHeaderMap(headers)));
+ response_array.emplace_back(CreateByteString(payload));
+ cbor::Value response(response_array);
+ int64_t response_length = EncodedLength(response);
+ ResponseLocation result = {current_responses_offset_, response_length};
+ current_responses_offset_ += response_length;
+ responses_.emplace_back(std::move(response));
+ return result;
+}
+
+void WebBundleBuilder::AddIndexEntry(
+ base::StringPiece url,
+ base::StringPiece variants_value,
+ std::vector<ResponseLocation> response_locations) {
+ cbor::Value::ArrayValue index_value_array;
+ index_value_array.emplace_back(CreateByteString(variants_value));
+ for (const auto& location : response_locations) {
+ index_value_array.emplace_back(location.offset);
+ index_value_array.emplace_back(location.length);
+ }
+ index_.insert({cbor::Value::InvalidUTF8StringValueForTesting(url),
+ cbor::Value(index_value_array)});
+}
+
+void WebBundleBuilder::AddSection(base::StringPiece name, cbor::Value section) {
+ section_lengths_.emplace_back(name);
+ section_lengths_.emplace_back(EncodedLength(section));
+ sections_.emplace_back(std::move(section));
+}
+
+void WebBundleBuilder::AddAuthority(cbor::Value::MapValue authority) {
+ authorities_.emplace_back(std::move(authority));
+}
+
+void WebBundleBuilder::AddVouchedSubset(cbor::Value::MapValue vouched_subset) {
+ vouched_subsets_.emplace_back(std::move(vouched_subset));
+}
+
+std::vector<uint8_t> WebBundleBuilder::CreateBundle() {
+ AddSection("index", cbor::Value(index_));
+ if (!authorities_.empty() || !vouched_subsets_.empty()) {
+ cbor::Value::ArrayValue signatures_section;
+ signatures_section.emplace_back(std::move(authorities_));
+ signatures_section.emplace_back(std::move(vouched_subsets_));
+ AddSection("signatures", cbor::Value(std::move(signatures_section)));
+ }
+ AddSection("responses", cbor::Value(responses_));
+ return Encode(CreateTopLevel());
+}
+
+cbor::Value WebBundleBuilder::CreateEncodedSigned(
+ base::StringPiece validity_url,
+ base::StringPiece auth_sha256,
+ int64_t date,
+ int64_t expires,
+ base::StringPiece url,
+ base::StringPiece header_sha256,
+ base::StringPiece payload_integrity_header) {
+ cbor::Value::ArrayValue subset_hash_value;
+ subset_hash_value.emplace_back(CreateByteString("")); // variants-value
+ subset_hash_value.emplace_back(CreateByteString(header_sha256));
+ subset_hash_value.emplace_back(payload_integrity_header);
+
+ cbor::Value::MapValue subset_hashes;
+ subset_hashes.emplace(url, std::move(subset_hash_value));
+
+ cbor::Value::MapValue signed_subset;
+ signed_subset.emplace("validity-url", validity_url);
+ signed_subset.emplace("auth-sha256", CreateByteString(auth_sha256));
+ signed_subset.emplace("date", date);
+ signed_subset.emplace("expires", expires);
+ signed_subset.emplace("subset-hashes", std::move(subset_hashes));
+ return cbor::Value(Encode(cbor::Value(signed_subset)));
+}
+
+cbor::Value WebBundleBuilder::CreateTopLevel() {
+ cbor::Value::ArrayValue toplevel_array;
+ toplevel_array.emplace_back(
+ CreateByteString(u8"\U0001F310\U0001F4E6")); // "🌐📦"
+ toplevel_array.emplace_back(CreateByteString(base::StringPiece("b1\0\0", 4)));
+ toplevel_array.emplace_back(
+ cbor::Value::InvalidUTF8StringValueForTesting(fallback_url_));
+ toplevel_array.emplace_back(Encode(cbor::Value(section_lengths_)));
+ toplevel_array.emplace_back(sections_);
+ toplevel_array.emplace_back(CreateByteString("")); // length (ignored)
+ return cbor::Value(toplevel_array);
+}
+
+std::vector<uint8_t> WebBundleBuilder::Encode(const cbor::Value& value) {
+ return *cbor::Writer::Write(value, writer_config_);
+}
+
+int64_t WebBundleBuilder::EncodedLength(const cbor::Value& value) {
+ return Encode(value).size();
+}
+
+} // namespace test
+} // namespace data_decoder
diff --git a/chromium/services/data_decoder/public/cpp/test_support/web_bundle_builder.h b/chromium/services/data_decoder/public/cpp/test_support/web_bundle_builder.h
new file mode 100644
index 00000000000..71267ac3ec7
--- /dev/null
+++ b/chromium/services/data_decoder/public/cpp/test_support/web_bundle_builder.h
@@ -0,0 +1,80 @@
+// Copyright 2020 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 SERVICES_DATA_DECODER_PUBLIC_CPP_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_
+#define SERVICES_DATA_DECODER_PUBLIC_CPP_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/strings/string_piece.h"
+#include "components/cbor/writer.h"
+
+namespace data_decoder {
+namespace test {
+
+// This class can be used to create a Web Bundle binary in tests.
+class WebBundleBuilder {
+ public:
+ using Headers = std::vector<std::pair<std::string, std::string>>;
+ struct ResponseLocation {
+ // /components/cbor uses int64_t for integer types.
+ int64_t offset;
+ int64_t length;
+ };
+
+ WebBundleBuilder(const std::string& fallback_url,
+ const std::string& manifest_url);
+ ~WebBundleBuilder();
+
+ void AddExchange(base::StringPiece url,
+ const Headers& response_headers,
+ base::StringPiece payload);
+
+ ResponseLocation AddResponse(const Headers& headers,
+ base::StringPiece payload);
+
+ void AddIndexEntry(base::StringPiece url,
+ base::StringPiece variants_value,
+ std::vector<ResponseLocation> response_locations);
+ void AddSection(base::StringPiece name, cbor::Value section);
+ void AddAuthority(cbor::Value::MapValue authority);
+ void AddVouchedSubset(cbor::Value::MapValue vouched_subset);
+
+ std::vector<uint8_t> CreateBundle();
+
+ // Creates a signed-subset structure with single subset-hashes entry,
+ // and returns it as a CBOR bytestring.
+ cbor::Value CreateEncodedSigned(base::StringPiece validity_url,
+ base::StringPiece auth_sha256,
+ int64_t date,
+ int64_t expires,
+ base::StringPiece url,
+ base::StringPiece header_sha256,
+ base::StringPiece payload_integrity_header);
+
+ private:
+ cbor::Value CreateTopLevel();
+ std::vector<uint8_t> Encode(const cbor::Value& value);
+
+ int64_t EncodedLength(const cbor::Value& value);
+
+ cbor::Writer::Config writer_config_;
+ std::string fallback_url_;
+ cbor::Value::ArrayValue section_lengths_;
+ cbor::Value::ArrayValue sections_;
+ cbor::Value::MapValue index_;
+ cbor::Value::ArrayValue responses_;
+ cbor::Value::ArrayValue authorities_;
+ cbor::Value::ArrayValue vouched_subsets_;
+
+ // 1 for the CBOR header byte. See the comment at the top of AddResponse().
+ int64_t current_responses_offset_ = 1;
+};
+
+} // namespace test
+} // namespace data_decoder
+
+#endif // SERVICES_DATA_DECODER_PUBLIC_CPP_TEST_SUPPORT_WEB_BUNDLE_BUILDER_H_
diff --git a/chromium/services/data_decoder/public/mojom/BUILD.gn b/chromium/services/data_decoder/public/mojom/BUILD.gn
index 435acd818f3..ee6240f24a1 100644
--- a/chromium/services/data_decoder/public/mojom/BUILD.gn
+++ b/chromium/services/data_decoder/public/mojom/BUILD.gn
@@ -10,11 +10,12 @@ mojom("mojom") {
"image_decoder.mojom",
"json_parser.mojom",
"web_bundle_parser.mojom",
+ "web_bundler.mojom",
"xml_parser.mojom",
]
public_deps = [
- ":constants",
+ ":mojom_resource_snapshot_for_web_bundle",
"//mojo/public/mojom/base",
"//skia/public/mojom",
"//ui/gfx/geometry/mojom",
@@ -27,8 +28,18 @@ mojom("mojom") {
}
}
-mojom("constants") {
- sources = [
- "constants.mojom",
+mojom("mojom_resource_snapshot_for_web_bundle") {
+ generate_java = true
+ sources = [ "resource_snapshot_for_web_bundle.mojom" ]
+
+ public_deps = [
+ "//mojo/public/mojom/base",
+ "//url/mojom:url_mojom_gurl",
]
+
+ if (!is_ios) {
+ export_class_attribute_blink = "BLINK_PLATFORM_EXPORT"
+ export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1"
+ export_header_blink = "third_party/blink/public/platform/web_common.h"
+ }
}
diff --git a/chromium/services/data_decoder/public/mojom/constants.mojom b/chromium/services/data_decoder/public/mojom/constants.mojom
deleted file mode 100644
index 60a96f275bd..00000000000
--- a/chromium/services/data_decoder/public/mojom/constants.mojom
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2016 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 data_decoder.mojom;
-
-const string kServiceName = "data_decoder";
diff --git a/chromium/services/data_decoder/public/mojom/data_decoder_service.mojom b/chromium/services/data_decoder/public/mojom/data_decoder_service.mojom
index 420b6d1552b..120ba37e7d4 100644
--- a/chromium/services/data_decoder/public/mojom/data_decoder_service.mojom
+++ b/chromium/services/data_decoder/public/mojom/data_decoder_service.mojom
@@ -6,6 +6,7 @@ module data_decoder.mojom;
import "services/data_decoder/public/mojom/image_decoder.mojom";
import "services/data_decoder/public/mojom/json_parser.mojom";
+import "services/data_decoder/public/mojom/web_bundler.mojom";
import "services/data_decoder/public/mojom/web_bundle_parser.mojom";
import "services/data_decoder/public/mojom/xml_parser.mojom";
@@ -27,6 +28,9 @@ interface DataDecoderService {
BindWebBundleParserFactory(
pending_receiver<WebBundleParserFactory> receiver);
+ // Binds an interface which can be used to generate a Web Bundle.
+ BindWebBundler(pending_receiver<WebBundler> receiver);
+
// Binds an interface which can be used to parse raw BLE advertising packet
// data.
[EnableIf=is_chromeos]
diff --git a/chromium/services/data_decoder/public/mojom/image_decoder.mojom b/chromium/services/data_decoder/public/mojom/image_decoder.mojom
index 59f6a28ad1a..741e39c629f 100644
--- a/chromium/services/data_decoder/public/mojom/image_decoder.mojom
+++ b/chromium/services/data_decoder/public/mojom/image_decoder.mojom
@@ -10,7 +10,6 @@ import "ui/gfx/geometry/mojom/geometry.mojom";
enum ImageCodec {
DEFAULT,
- ROBUST_JPEG,
ROBUST_PNG,
};
diff --git a/chromium/services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom b/chromium/services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom
new file mode 100644
index 00000000000..13408416fb0
--- /dev/null
+++ b/chromium/services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom
@@ -0,0 +1,26 @@
+// Copyright 2020 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 data_decoder.mojom;
+
+import "mojo/public/mojom/base/big_buffer.mojom";
+import "url/mojom/url.mojom";
+
+struct SerializedResourceInfo {
+ url.mojom.Url url;
+ string mime_type;
+ uint64 size;
+};
+
+// An interface to get resource snapshot of a frame to generate a web bundle.
+// This interface is implemented by renderer processes. Its end point is set-up
+// by the browser process and then passed to the utility process.
+interface ResourceSnapshotForWebBundle {
+ // Returns the resource count.
+ GetResourceCount() => (uint64 count);
+ // Returns the resource info at the index.
+ GetResourceInfo(uint64 index) => (SerializedResourceInfo? info);
+ // Returns the body of the resource at the index.
+ GetResourceBody(uint64 index) => (mojo_base.mojom.BigBuffer? data);
+};
diff --git a/chromium/services/data_decoder/public/mojom/web_bundle_parser.mojom b/chromium/services/data_decoder/public/mojom/web_bundle_parser.mojom
index b912e5bd526..ca4c1be70a5 100644
--- a/chromium/services/data_decoder/public/mojom/web_bundle_parser.mojom
+++ b/chromium/services/data_decoder/public/mojom/web_bundle_parser.mojom
@@ -34,7 +34,8 @@ interface WebBundleParser {
// Data source that provides application/webbundle data to the parser.
interface BundleDataSource {
- GetSize() => (uint64 size);
+ // Reads up to |length| bytes starting with |offset|. Returns a non-null
+ // buffer shorter than |length| iff the end of the stream is reached.
Read(uint64 offset, uint64 length) => (array<uint8>? buffer);
};
diff --git a/chromium/services/data_decoder/public/mojom/web_bundler.mojom b/chromium/services/data_decoder/public/mojom/web_bundler.mojom
new file mode 100644
index 00000000000..879e0f7b860
--- /dev/null
+++ b/chromium/services/data_decoder/public/mojom/web_bundler.mojom
@@ -0,0 +1,24 @@
+// Copyright 2020 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 data_decoder.mojom;
+
+import "services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom";
+import "mojo/public/mojom/base/file.mojom";
+
+enum WebBundlerError {
+ kOK,
+ kNotImplemented,
+ kFileOpenFailed,
+ kWebBundlerConnectionError,
+};
+
+// Bundler interface to generate a web bundle from snapshots.
+interface WebBundler {
+ // Generates a web bundle from |snapshots| and writes to the passed |file|.
+ Generate(
+ array<pending_remote<ResourceSnapshotForWebBundle>> snapshots,
+ mojo_base.mojom.File file)
+ => (uint64 file_size, WebBundlerError error);
+};
diff --git a/chromium/services/data_decoder/web_bundle_parser.cc b/chromium/services/data_decoder/web_bundle_parser.cc
index f140da1842c..e354823ca31 100644
--- a/chromium/services/data_decoder/web_bundle_parser.cc
+++ b/chromium/services/data_decoder/web_bundle_parser.cc
@@ -311,30 +311,22 @@ class WebBundleParser::MetadataParser
~MetadataParser() override { data_source_->RemoveObserver(this); }
void Start() {
- data_source_->GetSize(base::BindOnce(&MetadataParser::DidGetSize,
- weak_factory_.GetWeakPtr()));
- }
-
- private:
- void DidGetSize(uint64_t size) {
- size_ = size;
-
- // In the next step, we will parse `magic`, `version`, and the CBOR
- // header of `primary-url`.
+ // First, we will parse `magic`, `version`, and the CBOR header of
+ // `primary-url`.
// https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#top-level
- const uint64_t length = std::min(size, sizeof(kBundleMagicBytes) +
- sizeof(kVersionB1MagicBytes) +
- kMaxCBORItemHeaderSize);
+ const uint64_t length = sizeof(kBundleMagicBytes) +
+ sizeof(kVersionB1MagicBytes) +
+ kMaxCBORItemHeaderSize;
data_source_->Read(0, length,
base::BindOnce(&MetadataParser::ParseMagicBytes,
- weak_factory_.GetWeakPtr(), length));
+ weak_factory_.GetWeakPtr()));
}
+ private:
// Step 1-4 of
// https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-metadata
- void ParseMagicBytes(uint64_t expected_data_length,
- const base::Optional<std::vector<uint8_t>>& data) {
- if (!data || data->size() != expected_data_length) {
+ void ParseMagicBytes(const base::Optional<std::vector<uint8_t>>& data) {
+ if (!data) {
RunErrorCallbackAndDestroy("Error reading bundle magic bytes.");
return;
}
@@ -381,22 +373,20 @@ class WebBundleParser::MetadataParser
// In the next step, we will parse the content of `primary-url`,
// `section-lengths`, and the CBOR header of `sections`.
- const uint64_t length = std::min(
- size_ - input.CurrentOffset(),
- *url_length + kMaxSectionLengthsCBORSize + kMaxCBORItemHeaderSize * 2);
+ const uint64_t length =
+ *url_length + kMaxSectionLengthsCBORSize + kMaxCBORItemHeaderSize * 2;
data_source_->Read(input.CurrentOffset(), length,
base::BindOnce(&MetadataParser::ParseBundleHeader,
- weak_factory_.GetWeakPtr(), length,
- *url_length, input.CurrentOffset()));
+ weak_factory_.GetWeakPtr(), *url_length,
+ input.CurrentOffset()));
}
// Step 5-21 of
// https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#load-metadata
- void ParseBundleHeader(uint64_t expected_data_length,
- uint64_t url_length,
+ void ParseBundleHeader(uint64_t url_length,
uint64_t offset_in_stream,
const base::Optional<std::vector<uint8_t>>& data) {
- if (!data || data->size() != expected_data_length) {
+ if (!data) {
RunErrorCallbackAndDestroy("Error reading bundle header.");
return;
}
@@ -534,9 +524,9 @@ class WebBundleParser::MetadataParser
// Step 19.4. "Set currentOffset to currentOffset + length."
if (!base::CheckAdd(current_offset, length)
- .AssignIfValid(&current_offset) ||
- current_offset > size_) {
- RunErrorCallbackAndDestroy("Section doesn't fit in the bundle.");
+ .AssignIfValid(&current_offset)) {
+ RunErrorCallbackAndDestroy(
+ "Integer overflow calculating section offsets.");
return;
}
}
@@ -1098,7 +1088,6 @@ class WebBundleParser::MetadataParser
scoped_refptr<SharedBundleDataSource> data_source_;
ParseMetadataCallback callback_;
- uint64_t size_;
bool version_mismatch_ = false;
GURL fallback_url_;
SectionOffsets section_offsets_;
@@ -1325,11 +1314,6 @@ void WebBundleParser::SharedBundleDataSource::OnDisconnect() {
observer->OnDisconnect();
}
-void WebBundleParser::SharedBundleDataSource::GetSize(
- GetSizeCallback callback) {
- data_source_->GetSize(std::move(callback));
-}
-
void WebBundleParser::SharedBundleDataSource::Read(uint64_t offset,
uint64_t length,
ReadCallback callback) {
diff --git a/chromium/services/data_decoder/web_bundle_parser.h b/chromium/services/data_decoder/web_bundle_parser.h
index 3be1cb99385..81fe780badc 100644
--- a/chromium/services/data_decoder/web_bundle_parser.h
+++ b/chromium/services/data_decoder/web_bundle_parser.h
@@ -39,7 +39,6 @@ class WebBundleParser : public mojom::WebBundleParser {
void RemoveObserver(Observer* observer);
// Implements mojom::BundleDataSource.
- void GetSize(GetSizeCallback callback) override;
void Read(uint64_t offset, uint64_t length, ReadCallback callback) override;
private:
diff --git a/chromium/services/data_decoder/web_bundle_parser_factory.cc b/chromium/services/data_decoder/web_bundle_parser_factory.cc
index 413d97f2c0f..1ead65ea90c 100644
--- a/chromium/services/data_decoder/web_bundle_parser_factory.cc
+++ b/chromium/services/data_decoder/web_bundle_parser_factory.cc
@@ -24,17 +24,15 @@ class FileDataSource final : public mojom::BundleDataSource {
private:
// Implements mojom::BundleDataSource.
- void GetSize(GetSizeCallback callback) override {
- std::move(callback).Run(file_.GetLength());
- }
void Read(uint64_t offset, uint64_t length, ReadCallback callback) override {
std::vector<uint8_t> buf(length);
- uint64_t bytes =
- file_.Read(offset, reinterpret_cast<char*>(buf.data()), length);
- if (bytes != length)
- std::move(callback).Run(base::nullopt);
- else
+ int bytes = file_.Read(offset, reinterpret_cast<char*>(buf.data()), length);
+ if (bytes > 0) {
+ buf.resize(bytes);
std::move(callback).Run(std::move(buf));
+ } else {
+ std::move(callback).Run(base::nullopt);
+ }
}
mojo::Receiver<mojom::BundleDataSource> receiver_;
diff --git a/chromium/services/data_decoder/web_bundle_parser_factory_unittest.cc b/chromium/services/data_decoder/web_bundle_parser_factory_unittest.cc
index 72728db3050..c6cecfa12f1 100644
--- a/chromium/services/data_decoder/web_bundle_parser_factory_unittest.cc
+++ b/chromium/services/data_decoder/web_bundle_parser_factory_unittest.cc
@@ -53,31 +53,7 @@ class WebBundleParserFactoryTest : public testing::Test {
base::test::TaskEnvironment task_environment_;
};
-TEST_F(WebBundleParserFactoryTest, GetSize) {
- base::FilePath test_file = base::FilePath(FILE_PATH_LITERAL("hello.wbn"));
-
- base::File file(GetTestFilePath(test_file),
- base::File::FLAG_OPEN | base::File::FLAG_READ);
- ASSERT_TRUE(file.IsValid());
- uint64_t file_size = file.GetLength();
-
- mojo::PendingRemote<mojom::BundleDataSource> remote;
- auto data_source = CreateFileDataSource(
- remote.InitWithNewPipeAndPassReceiver(), std::move(file));
-
- uint64_t result_size;
- base::RunLoop run_loop;
- data_source->GetSize(
- base::BindLambdaForTesting([&result_size, &run_loop](uint64_t size) {
- result_size = size;
- run_loop.QuitClosure().Run();
- }));
- run_loop.Run();
-
- EXPECT_EQ(file_size, result_size);
-}
-
-TEST_F(WebBundleParserFactoryTest, Read) {
+TEST_F(WebBundleParserFactoryTest, FileDataSource) {
base::FilePath test_file =
GetTestFilePath(base::FilePath(FILE_PATH_LITERAL("hello.wbn")));
@@ -141,6 +117,21 @@ TEST_F(WebBundleParserFactoryTest, Read) {
}));
run_loop.Run();
}
+ ASSERT_TRUE(result_data);
+ EXPECT_EQ(last16b, *result_data);
+
+ {
+ base::RunLoop run_loop;
+ data_source->Read(
+ file_length + 1, test_length,
+ base::BindLambdaForTesting(
+ [&result_data,
+ &run_loop](const base::Optional<std::vector<uint8_t>>& data) {
+ result_data = data;
+ run_loop.QuitClosure().Run();
+ }));
+ run_loop.Run();
+ }
ASSERT_FALSE(result_data);
}
diff --git a/chromium/services/data_decoder/web_bundle_parser_fuzzer.cc b/chromium/services/data_decoder/web_bundle_parser_fuzzer.cc
index 6d2aeba145e..df56a878f86 100644
--- a/chromium/services/data_decoder/web_bundle_parser_fuzzer.cc
+++ b/chromium/services/data_decoder/web_bundle_parser_fuzzer.cc
@@ -23,16 +23,13 @@ class DataSource : public data_decoder::mojom::BundleDataSource {
public:
DataSource(const uint8_t* data, size_t size) : data_(data), size_(size) {}
- void GetSize(GetSizeCallback callback) override {
- std::move(callback).Run(size_);
- }
-
void Read(uint64_t offset, uint64_t length, ReadCallback callback) override {
- if (offset + length > size_) {
+ if (offset >= size_) {
std::move(callback).Run(base::nullopt);
return;
}
const uint8_t* start = data_ + offset;
+ length = std::min(length, size_ - offset);
std::move(callback).Run(std::vector<uint8_t>(start, start + length));
}
@@ -64,8 +61,8 @@ class WebBundleParserFuzzer {
std::move(data_source_remote));
quit_loop_ = run_loop->QuitClosure();
- parser_->ParseMetadata(base::Bind(&WebBundleParserFuzzer::OnParseMetadata,
- base::Unretained(this)));
+ parser_->ParseMetadata(base::BindOnce(
+ &WebBundleParserFuzzer::OnParseMetadata, base::Unretained(this)));
}
void OnParseMetadata(data_decoder::mojom::BundleMetadataPtr metadata,
@@ -87,9 +84,10 @@ class WebBundleParserFuzzer {
return;
}
- parser_->ParseResponse(locations_[index]->offset, locations_[index]->length,
- base::Bind(&WebBundleParserFuzzer::OnParseResponse,
- base::Unretained(this), index));
+ parser_->ParseResponse(
+ locations_[index]->offset, locations_[index]->length,
+ base::BindOnce(&WebBundleParserFuzzer::OnParseResponse,
+ base::Unretained(this), index));
}
void OnParseResponse(size_t index,
@@ -101,7 +99,7 @@ class WebBundleParserFuzzer {
private:
mojo::Remote<data_decoder::mojom::WebBundleParser> parser_;
DataSource data_source_;
- base::Closure quit_loop_;
+ base::OnceClosure quit_loop_;
std::vector<data_decoder::mojom::BundleResponseLocationPtr> locations_;
};
diff --git a/chromium/services/data_decoder/web_bundle_parser_unittest.cc b/chromium/services/data_decoder/web_bundle_parser_unittest.cc
index 34d940c6548..eb637bacf9e 100644
--- a/chromium/services/data_decoder/web_bundle_parser_unittest.cc
+++ b/chromium/services/data_decoder/web_bundle_parser_unittest.cc
@@ -12,6 +12,7 @@
#include "base/test/task_environment.h"
#include "components/cbor/writer.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
+#include "services/data_decoder/public/cpp/test_support/web_bundle_builder.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace data_decoder {
@@ -43,16 +44,14 @@ class TestDataSource : public mojom::BundleDataSource {
explicit TestDataSource(const std::vector<uint8_t>& data)
: data_(reinterpret_cast<const char*>(data.data()), data.size()) {}
- void GetSize(GetSizeCallback callback) override {
- std::move(callback).Run(data_.size());
- }
-
void Read(uint64_t offset, uint64_t length, ReadCallback callback) override {
- if (offset + length > data_.size())
+ if (offset >= data_.size())
std::move(callback).Run(base::nullopt);
const uint8_t* start =
reinterpret_cast<const uint8_t*>(data_.data()) + offset;
- std::move(callback).Run(std::vector<uint8_t>(start, start + length));
+ uint64_t available_length = std::min(length, data_.size() - offset);
+ std::move(callback).Run(
+ std::vector<uint8_t>(start, start + available_length));
}
base::StringPiece GetPayload(const mojom::BundleResponsePtr& response) {
@@ -151,157 +150,6 @@ std::string AsString(const std::vector<uint8_t>& data) {
return std::string(reinterpret_cast<const char*>(data.data()), data.size());
}
-class BundleBuilder {
- public:
- using Headers = std::vector<std::pair<std::string, std::string>>;
- struct ResponseLocation {
- // /components/cbor uses int64_t for integer types.
- int64_t offset;
- int64_t length;
- };
-
- BundleBuilder(const std::string& fallback_url,
- const std::string& manifest_url)
- : fallback_url_(fallback_url) {
- writer_config_.allow_invalid_utf8_for_testing = true;
- if (!manifest_url.empty()) {
- AddSection("manifest",
- cbor::Value::InvalidUTF8StringValueForTesting(manifest_url));
- }
- }
-
- void AddExchange(base::StringPiece url,
- const Headers& response_headers,
- base::StringPiece payload) {
- AddIndexEntry(url, "", {AddResponse(response_headers, payload)});
- }
-
- ResponseLocation AddResponse(const Headers& headers,
- base::StringPiece payload) {
- // We assume that the size of the CBOR header of the responses array is 1,
- // which is true only if the responses array has no more than 23 elements.
- EXPECT_LT(responses_.size(), 23u)
- << "BundleBuilder cannot create bundles with more than 23 responses";
-
- cbor::Value::ArrayValue response_array;
- response_array.emplace_back(Encode(CreateHeaderMap(headers)));
- response_array.emplace_back(CreateByteString(payload));
- cbor::Value response(response_array);
- int64_t response_length = EncodedLength(response);
- ResponseLocation result = {current_responses_offset_, response_length};
- current_responses_offset_ += response_length;
- responses_.emplace_back(std::move(response));
- return result;
- }
-
- void AddIndexEntry(base::StringPiece url,
- base::StringPiece variants_value,
- std::vector<ResponseLocation> response_locations) {
- cbor::Value::ArrayValue index_value_array;
- index_value_array.emplace_back(CreateByteString(variants_value));
- for (const auto& location : response_locations) {
- index_value_array.emplace_back(location.offset);
- index_value_array.emplace_back(location.length);
- }
- index_.insert({cbor::Value::InvalidUTF8StringValueForTesting(url),
- cbor::Value(index_value_array)});
- }
-
- void AddSection(base::StringPiece name, cbor::Value section) {
- section_lengths_.emplace_back(name);
- section_lengths_.emplace_back(EncodedLength(section));
- sections_.emplace_back(std::move(section));
- }
-
- void AddAuthority(cbor::Value::MapValue authority) {
- authorities_.emplace_back(std::move(authority));
- }
-
- void AddVouchedSubset(cbor::Value::MapValue vouched_subset) {
- vouched_subsets_.emplace_back(std::move(vouched_subset));
- }
-
- std::vector<uint8_t> CreateBundle() {
- AddSection("index", cbor::Value(index_));
- if (!authorities_.empty() || !vouched_subsets_.empty()) {
- cbor::Value::ArrayValue signatures_section;
- signatures_section.emplace_back(std::move(authorities_));
- signatures_section.emplace_back(std::move(vouched_subsets_));
- AddSection("signatures", cbor::Value(std::move(signatures_section)));
- }
- AddSection("responses", cbor::Value(responses_));
- return Encode(CreateTopLevel());
- }
-
- // Creates a signed-subset structure with single subset-hashes entry,
- // and returns it as a CBOR bytestring.
- cbor::Value CreateEncodedSigned(base::StringPiece validity_url,
- base::StringPiece auth_sha256,
- int64_t date,
- int64_t expires,
- base::StringPiece url,
- base::StringPiece header_sha256,
- base::StringPiece payload_integrity_header) {
- cbor::Value::ArrayValue subset_hash_value;
- subset_hash_value.emplace_back(CreateByteString("")); // variants-value
- subset_hash_value.emplace_back(CreateByteString(header_sha256));
- subset_hash_value.emplace_back(payload_integrity_header);
-
- cbor::Value::MapValue subset_hashes;
- subset_hashes.emplace(url, std::move(subset_hash_value));
-
- cbor::Value::MapValue signed_subset;
- signed_subset.emplace("validity-url", validity_url);
- signed_subset.emplace("auth-sha256", CreateByteString(auth_sha256));
- signed_subset.emplace("date", date);
- signed_subset.emplace("expires", expires);
- signed_subset.emplace("subset-hashes", std::move(subset_hashes));
- return cbor::Value(Encode(cbor::Value(signed_subset)));
- }
-
- private:
- static cbor::Value CreateHeaderMap(const Headers& headers) {
- cbor::Value::MapValue map;
- for (const auto& pair : headers)
- map.insert({CreateByteString(pair.first), CreateByteString(pair.second)});
- return cbor::Value(std::move(map));
- }
-
- cbor::Value CreateTopLevel() {
- cbor::Value::ArrayValue toplevel_array;
- toplevel_array.emplace_back(
- CreateByteString(u8"\U0001F310\U0001F4E6")); // "🌐📦"
- toplevel_array.emplace_back(
- CreateByteString(base::StringPiece("b1\0\0", 4)));
- toplevel_array.emplace_back(
- cbor::Value::InvalidUTF8StringValueForTesting(fallback_url_));
- toplevel_array.emplace_back(Encode(cbor::Value(section_lengths_)));
- toplevel_array.emplace_back(sections_);
- toplevel_array.emplace_back(CreateByteString("")); // length (ignored)
- return cbor::Value(toplevel_array);
- }
-
- std::vector<uint8_t> Encode(const cbor::Value& value) {
- return *cbor::Writer::Write(value, writer_config_);
- }
-
- int64_t EncodedLength(const cbor::Value& value) {
- return Encode(value).size();
- }
-
- cbor::Writer::Config writer_config_;
- std::string fallback_url_;
- cbor::Value::ArrayValue section_lengths_;
- cbor::Value::ArrayValue sections_;
- cbor::Value::MapValue index_;
- cbor::Value::ArrayValue responses_;
- cbor::Value::ArrayValue authorities_;
- cbor::Value::ArrayValue vouched_subsets_;
-
- // 1 for the CBOR header byte. See the comment at the top of AddResponse().
- int64_t current_responses_offset_ = 1;
-};
-
} // namespace
class WebBundleParserTest : public testing::Test {
@@ -310,7 +158,7 @@ class WebBundleParserTest : public testing::Test {
};
TEST_F(WebBundleParserTest, WrongMagic) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
std::vector<uint8_t> bundle = builder.CreateBundle();
bundle[3] ^= 1;
TestDataSource data_source(bundle);
@@ -322,7 +170,7 @@ TEST_F(WebBundleParserTest, WrongMagic) {
}
TEST_F(WebBundleParserTest, UnknownVersion) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
std::vector<uint8_t> bundle = builder.CreateBundle();
// Modify the version string from "b1\0\0" to "q1\0\0".
ASSERT_EQ(bundle[11], 'b');
@@ -336,7 +184,7 @@ TEST_F(WebBundleParserTest, UnknownVersion) {
}
TEST_F(WebBundleParserTest, FallbackURLIsNotUTF8) {
- BundleBuilder builder("https://test.example.com/\xcc", kManifestUrl);
+ test::WebBundleBuilder builder("https://test.example.com/\xcc", kManifestUrl);
std::vector<uint8_t> bundle = builder.CreateBundle();
TestDataSource data_source(bundle);
@@ -347,7 +195,8 @@ TEST_F(WebBundleParserTest, FallbackURLIsNotUTF8) {
}
TEST_F(WebBundleParserTest, FallbackURLHasFragment) {
- BundleBuilder builder("https://test.example.com/#fragment", kManifestUrl);
+ test::WebBundleBuilder builder("https://test.example.com/#fragment",
+ kManifestUrl);
std::vector<uint8_t> bundle = builder.CreateBundle();
TestDataSource data_source(bundle);
@@ -358,7 +207,7 @@ TEST_F(WebBundleParserTest, FallbackURLHasFragment) {
}
TEST_F(WebBundleParserTest, SectionLengthsTooLarge) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
std::string too_long_section_name(8192, 'x');
builder.AddSection(too_long_section_name, cbor::Value(0));
TestDataSource data_source(builder.CreateBundle());
@@ -367,7 +216,7 @@ TEST_F(WebBundleParserTest, SectionLengthsTooLarge) {
}
TEST_F(WebBundleParserTest, DuplicateSectionName) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddSection("foo", cbor::Value(0));
builder.AddSection("foo", cbor::Value(0));
TestDataSource data_source(builder.CreateBundle());
@@ -376,7 +225,7 @@ TEST_F(WebBundleParserTest, DuplicateSectionName) {
}
TEST_F(WebBundleParserTest, SingleEntry) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -396,7 +245,7 @@ TEST_F(WebBundleParserTest, SingleEntry) {
}
TEST_F(WebBundleParserTest, InvalidRequestURL) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("", {{":status", "200"}, {"content-type", "text/plain"}},
"payload");
TestDataSource data_source(builder.CreateBundle());
@@ -405,7 +254,7 @@ TEST_F(WebBundleParserTest, InvalidRequestURL) {
}
TEST_F(WebBundleParserTest, RequestURLIsNotUTF8) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/\xcc",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -415,7 +264,7 @@ TEST_F(WebBundleParserTest, RequestURLIsNotUTF8) {
}
TEST_F(WebBundleParserTest, RequestURLHasBadScheme) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("file:///tmp/foo",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -425,7 +274,7 @@ TEST_F(WebBundleParserTest, RequestURLHasBadScheme) {
}
TEST_F(WebBundleParserTest, RequestURLHasCredentials) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://user:passwd@test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -435,7 +284,7 @@ TEST_F(WebBundleParserTest, RequestURLHasCredentials) {
}
TEST_F(WebBundleParserTest, RequestURLHasFragment) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/#fragment",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -445,7 +294,7 @@ TEST_F(WebBundleParserTest, RequestURLHasFragment) {
}
TEST_F(WebBundleParserTest, NoStatusInResponseHeaders) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{"content-type", "text/plain"}},
"payload"); // ":status" is missing.
@@ -459,7 +308,7 @@ TEST_F(WebBundleParserTest, NoStatusInResponseHeaders) {
}
TEST_F(WebBundleParserTest, InvalidResponseStatus) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "0200"}, {"content-type", "text/plain"}},
"payload");
@@ -473,7 +322,7 @@ TEST_F(WebBundleParserTest, InvalidResponseStatus) {
}
TEST_F(WebBundleParserTest, ExtraPseudoInResponseHeaders) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange(
"https://test.example.com/",
{{":status", "200"}, {":foo", ""}, {"content-type", "text/plain"}},
@@ -488,7 +337,7 @@ TEST_F(WebBundleParserTest, ExtraPseudoInResponseHeaders) {
}
TEST_F(WebBundleParserTest, UpperCaseCharacterInHeaderName) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"Content-Type", "text/plain"}},
"payload");
@@ -502,7 +351,7 @@ TEST_F(WebBundleParserTest, UpperCaseCharacterInHeaderName) {
}
TEST_F(WebBundleParserTest, InvalidHeaderValue) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "\n"}}, "payload");
TestDataSource data_source(builder.CreateBundle());
@@ -515,7 +364,7 @@ TEST_F(WebBundleParserTest, InvalidHeaderValue) {
}
TEST_F(WebBundleParserTest, NoContentTypeWithNonEmptyContent) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/", {{":status", "200"}},
"payload");
TestDataSource data_source(builder.CreateBundle());
@@ -528,7 +377,7 @@ TEST_F(WebBundleParserTest, NoContentTypeWithNonEmptyContent) {
}
TEST_F(WebBundleParserTest, NoContentTypeWithEmptyContent) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/", {{":status", "301"}}, "");
TestDataSource data_source(builder.CreateBundle());
@@ -540,7 +389,7 @@ TEST_F(WebBundleParserTest, NoContentTypeWithEmptyContent) {
}
TEST_F(WebBundleParserTest, Variants) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
auto location1 = builder.AddResponse(
{{":status", "200"}, {"content-type", "text/html"}}, "payload1");
auto location2 = builder.AddResponse(
@@ -569,7 +418,7 @@ TEST_F(WebBundleParserTest, Variants) {
}
TEST_F(WebBundleParserTest, EmptyIndexEntry) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddIndexEntry("https://test.example.com/", "", {});
TestDataSource data_source(builder.CreateBundle());
@@ -577,7 +426,7 @@ TEST_F(WebBundleParserTest, EmptyIndexEntry) {
}
TEST_F(WebBundleParserTest, EmptyIndexEntryWithVariants) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddIndexEntry("https://test.example.com/",
"Accept;text/html;text/plain", {});
TestDataSource data_source(builder.CreateBundle());
@@ -586,7 +435,7 @@ TEST_F(WebBundleParserTest, EmptyIndexEntryWithVariants) {
}
TEST_F(WebBundleParserTest, MultipleResponsesWithoutVariantsValue) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
auto location1 = builder.AddResponse(
{{":status", "200"}, {"content-type", "text/html"}}, "payload1");
auto location2 = builder.AddResponse(
@@ -599,7 +448,7 @@ TEST_F(WebBundleParserTest, MultipleResponsesWithoutVariantsValue) {
}
TEST_F(WebBundleParserTest, AllKnownSectionInCritical) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -616,7 +465,7 @@ TEST_F(WebBundleParserTest, AllKnownSectionInCritical) {
}
TEST_F(WebBundleParserTest, UnknownSectionInCritical) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -629,7 +478,7 @@ TEST_F(WebBundleParserTest, UnknownSectionInCritical) {
}
TEST_F(WebBundleParserTest, NoManifest) {
- BundleBuilder builder(kFallbackUrl, std::string());
+ test::WebBundleBuilder builder(kFallbackUrl, std::string());
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -640,7 +489,7 @@ TEST_F(WebBundleParserTest, NoManifest) {
}
TEST_F(WebBundleParserTest, InvalidManifestURL) {
- BundleBuilder builder(kFallbackUrl, "not-an-absolute-url");
+ test::WebBundleBuilder builder(kFallbackUrl, "not-an-absolute-url");
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -650,11 +499,12 @@ TEST_F(WebBundleParserTest, InvalidManifestURL) {
}
TEST_F(WebBundleParserTest, EmptySignaturesSection) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
- // BundleBuilder omits signatures section if empty, so create it ourselves.
+ // test::WebBundleBuilder omits signatures section if empty, so create it
+ // ourselves.
cbor::Value::ArrayValue signatures_section;
signatures_section.emplace_back(cbor::Value::ArrayValue()); // authorities
signatures_section.emplace_back(
@@ -669,7 +519,7 @@ TEST_F(WebBundleParserTest, EmptySignaturesSection) {
}
TEST_F(WebBundleParserTest, SignaturesSection) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
@@ -728,7 +578,7 @@ TEST_F(WebBundleParserTest, SignaturesSection) {
}
TEST_F(WebBundleParserTest, MultipleSignatures) {
- BundleBuilder builder(kFallbackUrl, kManifestUrl);
+ test::WebBundleBuilder builder(kFallbackUrl, kManifestUrl);
builder.AddExchange("https://test.example.com/",
{{":status", "200"}, {"content-type", "text/plain"}},
"payload");
diff --git a/chromium/services/data_decoder/web_bundler.cc b/chromium/services/data_decoder/web_bundler.cc
new file mode 100644
index 00000000000..dd4537fd8da
--- /dev/null
+++ b/chromium/services/data_decoder/web_bundler.cc
@@ -0,0 +1,19 @@
+// Copyright 2020 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 "services/data_decoder/web_bundler.h"
+
+namespace data_decoder {
+
+void WebBundler::Generate(
+ std::vector<mojo::PendingRemote<mojom::ResourceSnapshotForWebBundle>>
+ snapshots,
+ base::File file,
+ GenerateCallback callback) {
+ // The Web Bundle generation logic is not implemented yet.
+ // TODO(crbug.com/1040752): Implement this.
+ std::move(callback).Run(0, mojom::WebBundlerError::kNotImplemented);
+}
+
+} // namespace data_decoder
diff --git a/chromium/services/data_decoder/web_bundler.h b/chromium/services/data_decoder/web_bundler.h
new file mode 100644
index 00000000000..36be2141048
--- /dev/null
+++ b/chromium/services/data_decoder/web_bundler.h
@@ -0,0 +1,37 @@
+// Copyright 2020 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 SERVICES_DATA_DECODER_WEB_BUNDLER_H_
+#define SERVICES_DATA_DECODER_WEB_BUNDLER_H_
+
+#include <vector>
+
+#include "base/files/file.h"
+#include "mojo/public/cpp/base/big_buffer.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom.h"
+#include "services/data_decoder/public/mojom/web_bundler.mojom.h"
+
+namespace data_decoder {
+
+class WebBundler : public mojom::WebBundler {
+ public:
+ WebBundler() = default;
+ ~WebBundler() override = default;
+
+ WebBundler(const WebBundler&) = delete;
+ WebBundler& operator=(const WebBundler&) = delete;
+
+ private:
+ // mojom::WebBundler implementation.
+ void Generate(
+ std::vector<mojo::PendingRemote<mojom::ResourceSnapshotForWebBundle>>
+ snapshots,
+ base::File file,
+ GenerateCallback callback) override;
+};
+
+} // namespace data_decoder
+
+#endif // SERVICES_DATA_DECODER_WEB_BUNDLER_H_
diff --git a/chromium/services/data_decoder/xml_parser_fuzzer.cc b/chromium/services/data_decoder/xml_parser_fuzzer.cc
index 8cd6f62dba4..7b23ff63a50 100644
--- a/chromium/services/data_decoder/xml_parser_fuzzer.cc
+++ b/chromium/services/data_decoder/xml_parser_fuzzer.cc
@@ -15,7 +15,7 @@
namespace {
-void OnParseXml(base::Closure quit_loop,
+void OnParseXml(base::OnceClosure quit_loop,
base::Optional<base::Value> value,
const base::Optional<std::string>& error) {
std::move(quit_loop).Run();
@@ -38,7 +38,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
base::SingleThreadTaskExecutor main_thread_task_executor;
base::RunLoop run_loop;
xml_parser.Parse(std::string(data_ptr, size),
- base::Bind(&OnParseXml, run_loop.QuitClosure()));
+ base::BindOnce(&OnParseXml, run_loop.QuitClosure()));
run_loop.Run();
return 0;
diff --git a/chromium/services/data_decoder/xml_parser_unittest.cc b/chromium/services/data_decoder/xml_parser_unittest.cc
index f0d7868e406..561826d2b52 100644
--- a/chromium/services/data_decoder/xml_parser_unittest.cc
+++ b/chromium/services/data_decoder/xml_parser_unittest.cc
@@ -35,7 +35,8 @@ void TestParseXml(const std::string& xml, const std::string& json) {
std::unique_ptr<base::Value> actual_value;
base::Optional<std::string> error;
- parser.Parse(xml, base::Bind(&TestParseXmlCallback, &actual_value, &error));
+ parser.Parse(xml,
+ base::BindOnce(&TestParseXmlCallback, &actual_value, &error));
if (json.empty()) {
EXPECT_TRUE(error);
EXPECT_FALSE(actual_value)