From 753fdc97548b01329dd85794c64f205e2fa8821e Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Tue, 8 Nov 2016 00:42:36 +0100 Subject: [PATCH] Bug 1151899 - Add code to run both URL parsers at the same time; r=bagder,ted,valentin MozReview-Commit-ID: Jd2RgPmdPrn --HG-- extra : rebase_source : ed9e5b027800a7a6ccbb443b294e208404bc5b01 --- browser/confvars.sh | 6 +- netwerk/base/moz.build | 2 +- netwerk/base/nsStandardURL.cpp | 149 +++++++++++++++++++++++--- netwerk/base/nsStandardURL.h | 5 + netwerk/base/rust-url-capi/src/lib.rs | 4 +- old-configure.in | 1 + 6 files changed, 150 insertions(+), 17 deletions(-) diff --git a/browser/confvars.sh b/browser/confvars.sh index d45b9221fe4b..64ec0031ec12 100755 --- a/browser/confvars.sh +++ b/browser/confvars.sh @@ -29,6 +29,11 @@ if test "$OS_ARCH" = "WINNT"; then fi fi +if test "$MOZ_UPDATE_CHANNEL" = "default" -o \ + "$MOZ_UPDATE_CHANNEL" = "nightly"; then + MOZ_RUST_URLPARSE=1 +fi + # Enable building ./signmar and running libmar signature tests MOZ_ENABLE_SIGNMAR=1 @@ -55,7 +60,6 @@ MOZ_APP_STATIC_INI=1 MOZ_WEBGL_CONFORMANT=1 MOZ_JSDOWNLOADS=1 MOZ_RUST_MP4PARSE=1 -MOZ_RUST_URLPARSE=1 # Enable checking that add-ons are signed by the trusted root MOZ_ADDON_SIGNING=1 diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index 84e5fe1e7f9b..577e3d2bac66 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -259,7 +259,7 @@ UNIFIED_SOURCES += [ 'TLSServerSocket.cpp', ] -if CONFIG['MOZ_RUST']: +if CONFIG['MOZ_RUST'] and CONFIG['MOZ_RUST_URLPARSE']: EXPORTS.mozilla.net += [ 'RustURL.h' ] UNIFIED_SOURCES += [ 'RustURL.cpp' ] diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index d3b1d35de7b4..1dd8cfe11998 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -27,6 +27,89 @@ #include "prprf.h" #include "nsReadableUtils.h" + +// +// setenv MOZ_LOG nsStandardURL:5 +// +static LazyLogModule gStandardURLLog("nsStandardURL"); + +// The Chromium code defines its own LOG macro which we don't want +#undef LOG +#define LOG(args) MOZ_LOG(gStandardURLLog, LogLevel::Debug, args) +#undef LOG_ENABLED +#define LOG_ENABLED() MOZ_LOG_TEST(gStandardURLLog, LogLevel::Debug) + +#ifdef MOZ_RUST_URLPARSE + +#include "RustURL.h" + +// Fall back to CPP-parsed URLs if the Rust one doesn't match. +#define MOZ_RUST_URLPARSE_FALLBACK + +#ifdef MOZ_RUST_URLPARSE_FALLBACK +#define MOZ_RUST_URLPARSE_FALLBACK_MACRO(expr) expr +#else +#define MOZ_RUST_URLPARSE_FALLBACK_MACRO(expr) +#endif + +#define CALL_RUST_SETTER(func, ...) \ +do { \ + mRustURL->func(__VA_ARGS__); \ + nsAutoCString rustSpec; \ + mRustURL->GetSpec(rustSpec); \ + if (mSpec != rustSpec) { \ + LOG(("Spec diff detected after setter (%s): rust: %s standard-url: %s\n", \ + #func, rustSpec.get(), mSpec.get())); \ + } \ +} while (0) + +#define CALL_RUST_GETTER_STR(result, func, ...) \ +do { \ + nsAutoCString backup(result); \ + mRustURL->func(__VA_ARGS__); \ + if (backup != result) { \ + LOG(("Diff detected calling getter (%s): rust: %s standard-url: %s\n", \ + #func, result.BeginReading() , backup.BeginReading())); \ + MOZ_RUST_URLPARSE_FALLBACK_MACRO(result = backup); \ + } \ +} while (0) + +#define CALL_RUST_GETTER_INT(result, func, ...) \ +do { \ + int32_t backup = *result; \ + mRustURL->func(__VA_ARGS__); \ + if (backup != *result) { \ + LOG(("Diff detected calling getter (%s): rust: %d standard-url: %d\n", \ + #func, *result , backup)); \ + MOZ_RUST_URLPARSE_FALLBACK_MACRO(*result = backup); \ + } \ +} while (0) + +#define COPY_RUST_MEMBER \ +do { \ + RefPtr url = new RustURL(); \ + nsAutoCString spec; \ + GetSpec(spec); \ + url->SetSpec(spec); \ + mRustURL = url; \ +} while (0) + +#define CALL_RUST_SYNC mRustURL->SetSpec(mSpec) +#define CALL_SET_MUTABLE mRustURL->SetMutable(value) +#define CALL_RUST_INIT mRustURL->Init(urlType, defaultPort, spec, charset, baseURI) + +#else + +#define CALL_RUST_SETTER(func, ...) +#define CALL_RUST_GETTER_STR(expected, func, ...) +#define CALL_RUST_GETTER_INT(expected, func, ...) +#define CALL_RUST_INIT +#define CALL_RUST_SYNC +#define CALL_SET_MUTABLE +#define COPY_RUST_MEMBER + +#endif // MOZ_RUST_URLPARSE + using mozilla::dom::EncodingUtils; using namespace mozilla::ipc; @@ -42,17 +125,6 @@ bool nsStandardURL::gEscapeUTF8 = true; bool nsStandardURL::gAlwaysEncodeInUTF8 = true; char nsStandardURL::gHostLimitDigits[] = { '/', '\\', '?', '#', 0 }; -// -// setenv MOZ_LOG nsStandardURL:5 -// -static LazyLogModule gStandardURLLog("nsStandardURL"); - -// The Chromium code defines its own LOG macro which we don't want -#undef LOG -#define LOG(args) MOZ_LOG(gStandardURLLog, LogLevel::Debug, args) -#undef LOG_ENABLED -#define LOG_ENABLED() MOZ_LOG_TEST(gStandardURLLog, LogLevel::Debug) - //---------------------------------------------------------------------------- #define ENSURE_MUTABLE() \ @@ -277,6 +349,10 @@ nsStandardURL::nsStandardURL(bool aSupportsFileURL, bool aTrackURL) } } #endif + +#ifdef MOZ_RUST_URLPARSE + mRustURL = new RustURL(); +#endif } nsStandardURL::~nsStandardURL() @@ -1205,6 +1281,7 @@ nsStandardURL::GetSpec(nsACString &result) MOZ_ASSERT(mSpec.Length() <= (uint32_t) net_GetURLMaxLength(), "The spec should never be this long, we missed a check."); result = mSpec; + CALL_RUST_GETTER_STR(result, GetSpec, result); return NS_OK; } @@ -1216,6 +1293,7 @@ nsStandardURL::GetSensitiveInfoHiddenSpec(nsACString &result) if (mPassword.mLen >= 0) { result.Replace(mPassword.mPos, mPassword.mLen, "****"); } + CALL_RUST_GETTER_STR(result, GetSensitiveInfoHiddenSpec, result); return NS_OK; } @@ -1231,6 +1309,7 @@ nsStandardURL::GetSpecIgnoringRef(nsACString &result) } else { result = mSpec; } + CALL_RUST_GETTER_STR(result, GetSpecIgnoringRef, result); return NS_OK; } @@ -1239,6 +1318,7 @@ NS_IMETHODIMP nsStandardURL::GetPrePath(nsACString &result) { result = Prepath(); + CALL_RUST_GETTER_STR(result, GetPrePath, result); return NS_OK; } @@ -1247,6 +1327,7 @@ NS_IMETHODIMP nsStandardURL::GetScheme(nsACString &result) { result = Scheme(); + CALL_RUST_GETTER_STR(result, GetScheme, result); return NS_OK; } @@ -1255,6 +1336,7 @@ NS_IMETHODIMP nsStandardURL::GetUserPass(nsACString &result) { result = Userpass(); + CALL_RUST_GETTER_STR(result, GetUserPass, result); return NS_OK; } @@ -1263,6 +1345,7 @@ NS_IMETHODIMP nsStandardURL::GetUsername(nsACString &result) { result = Username(); + CALL_RUST_GETTER_STR(result, GetUsername, result); return NS_OK; } @@ -1271,6 +1354,7 @@ NS_IMETHODIMP nsStandardURL::GetPassword(nsACString &result) { result = Password(); + CALL_RUST_GETTER_STR(result, GetPassword, result); return NS_OK; } @@ -1278,6 +1362,7 @@ NS_IMETHODIMP nsStandardURL::GetHostPort(nsACString &result) { result = Hostport(); + CALL_RUST_GETTER_STR(result, GetHostPort, result); return NS_OK; } @@ -1285,6 +1370,7 @@ NS_IMETHODIMP nsStandardURL::GetHost(nsACString &result) { result = Host(); + CALL_RUST_GETTER_STR(result, GetHost, result); return NS_OK; } @@ -1294,6 +1380,7 @@ nsStandardURL::GetPort(int32_t *result) // should never be more than 16 bit MOZ_ASSERT(mPort <= std::numeric_limits::max()); *result = mPort; + CALL_RUST_GETTER_INT(result, GetPort, result); return NS_OK; } @@ -1302,6 +1389,7 @@ NS_IMETHODIMP nsStandardURL::GetPath(nsACString &result) { result = Path(); + CALL_RUST_GETTER_STR(result, GetPath, result); return NS_OK; } @@ -1318,6 +1406,7 @@ nsStandardURL::GetAsciiSpec(nsACString &result) if (mSpecEncoding == eEncoding_ASCII) { result = mSpec; + CALL_RUST_GETTER_STR(result, GetAsciiSpec, result); return NS_OK; } @@ -1334,6 +1423,7 @@ nsStandardURL::GetAsciiSpec(nsACString &result) result += hostport; NS_EscapeURL(Path(), esc_OnlyNonASCII | esc_AlwaysCopy, result); + CALL_RUST_GETTER_STR(result, GetAsciiSpec, result); return NS_OK; } @@ -1343,6 +1433,7 @@ nsStandardURL::GetAsciiHostPort(nsACString &result) { if (mHostEncoding == eEncoding_ASCII) { result = Hostport(); + CALL_RUST_GETTER_STR(result, GetAsciiHostPort, result); return NS_OK; } @@ -1357,6 +1448,7 @@ nsStandardURL::GetAsciiHostPort(nsACString &result) if (pos < mPath.mPos) result += Substring(mSpec, pos, mPath.mPos - pos); + CALL_RUST_GETTER_STR(result, GetAsciiHostPort, result); return NS_OK; } @@ -1366,18 +1458,21 @@ nsStandardURL::GetAsciiHost(nsACString &result) { if (mHostEncoding == eEncoding_ASCII) { result = Host(); + CALL_RUST_GETTER_STR(result, GetAsciiHost, result); return NS_OK; } // perhaps we have it cached... if (mHostA) { result = mHostA; + CALL_RUST_GETTER_STR(result, GetAsciiHost, result); return NS_OK; } if (gIDN) { nsresult rv; rv = gIDN->ConvertUTF8toACE(Host(), result); + CALL_RUST_GETTER_STR(result, GetAsciiHost, result); if (NS_SUCCEEDED(rv)) { mHostA = ToNewCString(result); return NS_OK; @@ -1387,6 +1482,7 @@ nsStandardURL::GetAsciiHost(nsACString &result) // something went wrong... guess all we can do is URL escape :-/ NS_EscapeURL(Host(), esc_OnlyNonASCII | esc_AlwaysCopy, result); + CALL_RUST_GETTER_STR(result, GetAsciiHost, result); return NS_OK; } @@ -1397,6 +1493,7 @@ nsStandardURL::GetOriginCharset(nsACString &result) result.AssignLiteral("UTF-8"); else result = mOriginCharset; + CALL_RUST_GETTER_STR(result, GetOriginCharset, result); return NS_OK; } @@ -1501,6 +1598,8 @@ nsStandardURL::SetSpec(const nsACString &input) LOG((" query = (%u,%d)\n", mQuery.mPos, mQuery.mLen)); LOG((" ref = (%u,%d)\n", mRef.mPos, mRef.mLen)); } + + CALL_RUST_SETTER(SetSpec, input); return rv; } @@ -1545,6 +1644,7 @@ nsStandardURL::SetScheme(const nsACString &input) // XXX the string code unfortunately doesn't provide a ToLowerCase // that operates on a substring. net_ToLowerCase((char *) mSpec.get(), mScheme.mLen); + CALL_RUST_SETTER(SetScheme, input); return NS_OK; } @@ -1586,6 +1686,8 @@ nsStandardURL::SetUserPass(const nsACString &input) mUsername.mLen = -1; mPassword.mLen = -1; } + + CALL_RUST_SETTER(SetUserPass, input); return NS_OK; } @@ -1650,6 +1752,8 @@ nsStandardURL::SetUserPass(const nsACString &input) mPassword.mLen = passwordLen; if (passwordLen) mPassword.mPos = mUsername.mPos + mUsername.mLen + 1; + + CALL_RUST_SETTER(SetUserPass, input); return NS_OK; } @@ -1699,6 +1803,8 @@ nsStandardURL::SetUsername(const nsACString &input) mAuthority.mLen += shift; ShiftFromPassword(shift); } + + CALL_RUST_SETTER(SetUsername, input); return NS_OK; } @@ -1736,6 +1842,7 @@ nsStandardURL::SetPassword(const nsACString &input) mAuthority.mLen -= (mPassword.mLen + 1); mPassword.mLen = -1; } + CALL_RUST_SETTER(SetPassword, input); return NS_OK; } @@ -1760,6 +1867,7 @@ nsStandardURL::SetPassword(const nsACString &input) mAuthority.mLen += shift; ShiftFromHost(shift); } + CALL_RUST_SETTER(SetPassword, input); return NS_OK; } @@ -1843,7 +1951,7 @@ nsStandardURL::SetHostPort(const nsACString &aValue) return NS_ERROR_MALFORMED_URI; } } - + CALL_RUST_SETTER(SetHostPort, aValue); return NS_OK; } @@ -1856,6 +1964,7 @@ nsStandardURL::SetHostAndPort(const nsACString &aValue) // the port number. nsresult rv = SetPort(-1); NS_ENSURE_SUCCESS(rv, rv); + CALL_RUST_SETTER(SetHostAndPort, aValue); return SetHostPort(aValue); } @@ -1957,7 +2066,7 @@ nsStandardURL::SetHost(const nsACString &input) // Now canonicalize the host to lowercase net_ToLowerCase(mSpec.BeginWriting() + mHost.mPos, mHost.mLen); - + CALL_RUST_SETTER(SetHost, input); return NS_OK; } @@ -1989,6 +2098,7 @@ nsStandardURL::SetPort(int32_t port) ReplacePortInSpec(port); mPort = port; + CALL_RUST_SETTER(SetPort, port); return NS_OK; } @@ -2067,6 +2177,7 @@ nsStandardURL::SetPath(const nsACString &input) mQuery.mLen = -1; mRef.mLen = -1; } + CALL_RUST_SETTER(SetPath, input); return NS_OK; } @@ -2252,6 +2363,7 @@ nsresult nsStandardURL::CopyMembers(nsStandardURL * source, mSupportsFileURL = source->mSupportsFileURL; mHostEncoding = source->mHostEncoding; + COPY_RUST_MEMBER; if (copyCached) { mFile = source->mFile; mHostA = source->mHostA ? strdup(source->mHostA) : nullptr; @@ -2269,6 +2381,7 @@ nsresult nsStandardURL::CopyMembers(nsStandardURL * source, SetRef(newRef); } + return NS_OK; } @@ -2773,6 +2886,7 @@ nsStandardURL::SetQuery(const nsACString &input) mQuery.mPos = 0; mQuery.mLen = -1; } + CALL_RUST_SETTER(SetQuery, input); return NS_OK; } @@ -2813,6 +2927,7 @@ nsStandardURL::SetQuery(const nsACString &input) mPath.mLen += shift; ShiftFromRef(shift); } + CALL_RUST_SETTER(SetQuery, input); return NS_OK; } @@ -2844,6 +2959,7 @@ nsStandardURL::SetRef(const nsACString &input) mRef.mPos = 0; mRef.mLen = -1; } + CALL_RUST_SETTER(SetRef, input); return NS_OK; } @@ -2878,6 +2994,7 @@ nsStandardURL::SetRef(const nsACString &input) int32_t shift = ReplaceSegment(mRef.mPos, mRef.mLen, ref, refLen); mPath.mLen += shift; mRef.mLen = refLen; + CALL_RUST_SETTER(SetRef, input); return NS_OK; } @@ -3157,6 +3274,8 @@ nsStandardURL::Init(uint32_t urlType, baseURI = nullptr; } + CALL_RUST_INIT; + if (!baseURI) return SetSpec(spec); @@ -3204,6 +3323,7 @@ nsStandardURL::SetMutable(bool value) NS_ENSURE_ARG(mMutable || !value); mMutable = value; + CALL_SET_MUTABLE; return NS_OK; } @@ -3323,6 +3443,7 @@ nsStandardURL::Read(nsIObjectInputStream *stream) mExtension.Merge(mSpec, ';', old_param); } + CALL_RUST_SYNC; return NS_OK; } @@ -3513,6 +3634,8 @@ nsStandardURL::Deserialize(const URIParams& aParams) mSupportsFileURL = params.supportsFileURL(); mHostEncoding = params.hostEncoding(); + CALL_RUST_SYNC; + // mSpecEncoding and mHostA are just caches that can be recovered as needed. return true; } diff --git a/netwerk/base/nsStandardURL.h b/netwerk/base/nsStandardURL.h index 90f7f7db24a5..d61d6517759a 100644 --- a/netwerk/base/nsStandardURL.h +++ b/netwerk/base/nsStandardURL.h @@ -21,6 +21,7 @@ #include "mozilla/MemoryReporting.h" #include "nsIIPCSerializableURI.h" #include "nsISensitiveInfoHiddenURI.h" +#include "RustURL.h" #ifdef NS_BUILD_REFCNT_LOGGING #define DEBUG_DUMP_URLS_AT_SHUTDOWN @@ -310,6 +311,10 @@ public: PRCList mDebugCList; void PrintSpec() const { printf(" %s\n", mSpec.get()); } #endif + +#ifdef MOZ_RUST_URLPARSE + RefPtr mRustURL; +#endif }; #define NS_THIS_STANDARDURL_IMPL_CID \ diff --git a/netwerk/base/rust-url-capi/src/lib.rs b/netwerk/base/rust-url-capi/src/lib.rs index c2c5774c13d1..9d67adb2de49 100644 --- a/netwerk/base/rust-url-capi/src/lib.rs +++ b/netwerk/base/rust-url-capi/src/lib.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ extern crate url; -use url::{Url, ParseError, ParseOptions}; +use url::{Url, ParseError, ParseOptions, Position}; use url::quirks; extern crate libc; use libc::size_t; @@ -144,7 +144,7 @@ pub unsafe extern "C" fn rusturl_get_path(urlptr: rusturl_ptr, cont: *mut libc:: if url.cannot_be_a_base() { cont.set_size(0) } else { - cont.assign(url.path()) + cont.assign(&url[Position::BeforePath..]) } } diff --git a/old-configure.in b/old-configure.in index abd4f1bf00a9..566ca4235ef1 100644 --- a/old-configure.in +++ b/old-configure.in @@ -2442,6 +2442,7 @@ if test -n "$MOZ_RUST"; then fi if test -n "$MOZ_RUST_URLPARSE"; then AC_DEFINE(MOZ_RUST_URLPARSE) + AC_SUBST(MOZ_RUST_URLPARSE) fi fi