tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit bcb27f714ab3d80877fe1c29c90310bf839f54f0
parent dd5db50db5d86b0619da53f2acaef6d9b6354802
Author: pyoor <pyoor@users.noreply.github.com>
Date:   Thu, 20 Nov 2025 03:23:51 +0000

Bug 1998504 - Add Fuzz Target for URLPattern. r=truber,edgul

Differential Revision: https://phabricator.services.mozilla.com/D271461

Diffstat:
Adom/urlpattern/fuzztest/FuzzURLPattern.cpp | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adom/urlpattern/fuzztest/moz.build | 24++++++++++++++++++++++++
Mdom/urlpattern/moz.build | 7+++++++
3 files changed, 185 insertions(+), 0 deletions(-)

diff --git a/dom/urlpattern/fuzztest/FuzzURLPattern.cpp b/dom/urlpattern/fuzztest/FuzzURLPattern.cpp @@ -0,0 +1,154 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#include "FuzzedDataProvider.h" +#include "FuzzingInterface.h" +#include "js/RootingAPI.h" // JS::PersistentRooted +#include "mozilla/ErrorResult.h" // ErrorResult +#include "mozilla/dom/BindingDeclarations.h" // GlobalObject +#include "mozilla/dom/ScriptSettings.h" // AutoJSAPI +#include "mozilla/dom/SimpleGlobalObject.h" // SimpleGlobalObject +#include "mozilla/dom/URLPattern.h" // URLPattern class +#include "mozilla/dom/URLPatternBinding.h" // UTF8StringOrURLPatternInit, URLPatternOptions +#include "nsReadableUtils.h" // CopyUTF8toUTF16, CopyUTF16toUTF8 + +using namespace mozilla; +using namespace mozilla::dom; + +static MOZ_RUNINIT JS::PersistentRooted<JSObject*> global; + +static int FuzzingInit(int* argc, char*** argv) { + JSObject* simpleGlobal = + SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail); + global.init(mozilla::dom::RootingCx()); + global.set(simpleGlobal); + return 0; +} + +// Helper function to simulate JS->WebIDL UTF8String conversion +static void SanitizeToUTF8(const std::string& input, nsACString& output) { + nsAutoString utf16; + CopyUTF8toUTF16(mozilla::Span(input.data(), input.length()), utf16); + CopyUTF16toUTF8(utf16, output); +} + +// Helper function to create an optional baseURL string +static void MaybeCreateBaseURL(FuzzedDataProvider& fdp, + Optional<nsACString>& base, nsCString& baseUrl) { + if (fdp.ConsumeBool()) { + std::string str = fdp.ConsumeRandomLengthString(); + SanitizeToUTF8(str, baseUrl); + base = &baseUrl; + } +} + +static void CreateURLPatternInput(FuzzedDataProvider& fdp, + UTF8StringOrURLPatternInit& input) { + if (fdp.ConsumeBool()) { + // URLPatternInit + auto maybeSetField = [&fdp](auto& field) { + if (fdp.ConsumeBool()) { + std::string str = fdp.ConsumeRandomLengthString(); + nsCString sanitized; + SanitizeToUTF8(str, sanitized); + field.Construct(sanitized); + } + }; + + URLPatternInit& init = input.SetAsURLPatternInit(); + maybeSetField(init.mProtocol); + maybeSetField(init.mUsername); + maybeSetField(init.mPassword); + maybeSetField(init.mHostname); + maybeSetField(init.mPort); + maybeSetField(init.mPathname); + maybeSetField(init.mSearch); + maybeSetField(init.mHash); + maybeSetField(init.mBaseURL); + } else { + // Plain UTF8String + std::string str = fdp.ConsumeRandomLengthString(); + auto& utf8Str = input.RawSetAsUTF8String(); + SanitizeToUTF8(str, *reinterpret_cast<nsCString*>(&utf8Str)); + } +} + +static int FuzzingRunURLPattern(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp(data, size); + + AutoJSAPI jsapi; + MOZ_RELEASE_ASSERT(jsapi.Init(global)); + JSContext* cx = jsapi.cx(); + GlobalObject globalObj(cx, global); + + UTF8StringOrURLPatternInit input; + CreateURLPatternInput(fdp, input); + + URLPatternOptions options; + options.mIgnoreCase = fdp.ConsumeBool(); + + ErrorResult rv; + + RefPtr<URLPattern> pattern; + if (fdp.ConsumeBool()) { + pattern = URLPattern::Constructor(globalObj, input, options, rv); + } else { + nsCString base; + std::string str = fdp.ConsumeRandomLengthString(); + SanitizeToUTF8(str, base); + pattern = URLPattern::Constructor(globalObj, input, base, options, rv); + } + + if (MOZ_UNLIKELY(rv.Failed())) { + return 0; + } + + // Table of getters + using GetterFunc = void (URLPattern::*)(nsACString&) const; + static const GetterFunc kGetters[] = { + &URLPattern::GetProtocol, &URLPattern::GetUsername, + &URLPattern::GetPassword, &URLPattern::GetHostname, + &URLPattern::GetPort, &URLPattern::GetPathname, + &URLPattern::GetSearch, &URLPattern::GetHash, + }; + + while (fdp.remaining_bytes() > 0) { + uint8_t operation = fdp.ConsumeIntegralInRange<uint8_t>(0, 10); + if (operation <= 7) { + // Access getters + nsAutoCString result; + (pattern.get()->*kGetters[operation])(result); + } else if (operation == 8) { + (void)pattern->HasRegExpGroups(); + } else if (operation == 9) { + // Test + UTF8StringOrURLPatternInit testInput; + CreateURLPatternInput(fdp, testInput); + + Optional<nsACString> base; + nsCString baseUrl; + MaybeCreateBaseURL(fdp, base, baseUrl); + + ErrorResult testRv; + (void)pattern->Test(testInput, base, testRv); + } else if (operation == 10) { + // Exec + UTF8StringOrURLPatternInit execInput; + CreateURLPatternInput(fdp, execInput); + + Optional<nsACString> base; + nsCString baseUrl; + MaybeCreateBaseURL(fdp, base, baseUrl); + + Nullable<URLPatternResult> result; + ErrorResult execRv; + pattern->Exec(execInput, base, result, execRv); + } + } + + return 0; +} + +MOZ_FUZZING_INTERFACE_RAW(FuzzingInit, FuzzingRunURLPattern, URLPattern); diff --git a/dom/urlpattern/fuzztest/moz.build b/dom/urlpattern/fuzztest/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Library("FuzzingURLPattern") + +SOURCES += [ + "FuzzURLPattern.cpp", +] + +LOCAL_INCLUDES += [ + "/dom/base", + "/dom/ipc", + "/dom/urlpattern", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +# Add libFuzzer configuration directives +include("/tools/fuzzing/libfuzzer-config.mozbuild") + +FINAL_LIBRARY = "xul-gtest" diff --git a/dom/urlpattern/moz.build b/dom/urlpattern/moz.build @@ -11,6 +11,13 @@ EXPORTS.mozilla.dom += [ "URLPattern.h", ] +if CONFIG["FUZZING"]: + if CONFIG["FUZZING_INTERFACES"]: + TEST_DIRS += ["fuzztest"] + +# Add libFuzzer configuration directives +include("/tools/fuzzing/libfuzzer-config.mozbuild") + UNIFIED_SOURCES += ["URLPattern.cpp"] FINAL_LIBRARY = "xul"