Bug 1675540 - Perform URL sanity checks when changing it r=necko-reviewers,kershaw

Differential Revision: https://phabricator.services.mozilla.com/D104541
This commit is contained in:
Valentin Gosu 2021-02-17 08:54:03 +00:00
parent 410a4c846a
commit dbc436b39f
2 changed files with 49 additions and 20 deletions

View File

@ -231,13 +231,29 @@ nsStandardURL::nsStandardURL(bool aSupportsFileURL, bool aTrackURL)
#endif #endif
} }
// static static void CheckSegment(const nsStandardURL::URLSegment& aSeg,
void nsStandardURL::SanityCheck(const URLSegment& aSeg, const nsCString& aSpec) {
const nsCString& aSpec) {
MOZ_RELEASE_ASSERT(aSeg.mLen >= -1); MOZ_RELEASE_ASSERT(aSeg.mLen >= -1);
MOZ_RELEASE_ASSERT(aSeg.mLen < 0 || if (aSeg.mLen < 0) {
(aSeg.mPos + aSeg.mLen <= aSpec.Length() && return;
aSeg.mPos + aSeg.mLen >= aSeg.mPos)); }
MOZ_RELEASE_ASSERT(aSeg.mPos + aSeg.mLen <= aSpec.Length());
MOZ_RELEASE_ASSERT(aSeg.mPos + aSeg.mLen >= aSeg.mPos);
}
void nsStandardURL::SanityCheck() {
CheckSegment(mScheme, mSpec);
CheckSegment(mAuthority, mSpec);
CheckSegment(mUsername, mSpec);
CheckSegment(mPassword, mSpec);
CheckSegment(mHost, mSpec);
CheckSegment(mPath, mSpec);
CheckSegment(mFilepath, mSpec);
CheckSegment(mDirectory, mSpec);
CheckSegment(mBasename, mSpec);
CheckSegment(mExtension, mSpec);
CheckSegment(mQuery, mSpec);
CheckSegment(mRef, mSpec);
} }
nsStandardURL::~nsStandardURL() { nsStandardURL::~nsStandardURL() {
@ -252,18 +268,7 @@ nsStandardURL::~nsStandardURL() {
} }
#endif #endif
SanityCheck(mScheme, mSpec); SanityCheck();
SanityCheck(mAuthority, mSpec);
SanityCheck(mUsername, mSpec);
SanityCheck(mPassword, mSpec);
SanityCheck(mHost, mSpec);
SanityCheck(mPath, mSpec);
SanityCheck(mFilepath, mSpec);
SanityCheck(mDirectory, mSpec);
SanityCheck(mBasename, mSpec);
SanityCheck(mExtension, mSpec);
SanityCheck(mQuery, mSpec);
SanityCheck(mRef, mSpec);
} }
#ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
@ -1605,6 +1610,7 @@ nsresult nsStandardURL::SetSpecWithEncoding(const nsACString& input,
LOG((" ref = (%u,%d)\n", mRef.mPos, mRef.mLen)); LOG((" ref = (%u,%d)\n", mRef.mPos, mRef.mLen));
} }
SanityCheck();
return rv; return rv;
} }
@ -1632,6 +1638,8 @@ nsresult nsStandardURL::SetScheme(const nsACString& input) {
return NS_ERROR_MALFORMED_URI; return NS_ERROR_MALFORMED_URI;
} }
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
InvalidateCache(); InvalidateCache();
int32_t shift = ReplaceSegment(mScheme.mPos, mScheme.mLen, scheme); int32_t shift = ReplaceSegment(mScheme.mPos, mScheme.mLen, scheme);
@ -1671,6 +1679,7 @@ nsresult nsStandardURL::SetUserPass(const nsACString& input) {
return NS_ERROR_MALFORMED_URI; return NS_ERROR_MALFORMED_URI;
} }
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
InvalidateCache(); InvalidateCache();
NS_ASSERTION(mHost.mLen >= 0, "uninitialized"); NS_ASSERTION(mHost.mLen >= 0, "uninitialized");
@ -1770,6 +1779,8 @@ nsresult nsStandardURL::SetUsername(const nsACString& input) {
return NS_ERROR_MALFORMED_URI; return NS_ERROR_MALFORMED_URI;
} }
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
InvalidateCache(); InvalidateCache();
// escape username if necessary // escape username if necessary
@ -1823,6 +1834,8 @@ nsresult nsStandardURL::SetPassword(const nsACString& input) {
Unused << this; // silence compiler -Wunused-lambda-capture Unused << this; // silence compiler -Wunused-lambda-capture
}); });
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
LOG(("nsStandardURL::SetPassword [password=%s]\n", password.get())); LOG(("nsStandardURL::SetPassword [password=%s]\n", password.get()));
if (mURLType == URLTYPE_NO_AUTHORITY) { if (mURLType == URLTYPE_NO_AUTHORITY) {
@ -1941,6 +1954,8 @@ nsresult nsStandardURL::SetHostPort(const nsACString& aValue) {
} }
} }
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
nsresult rv = SetHost(Substring(start, iter)); nsresult rv = SetHost(Substring(start, iter));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -2012,6 +2027,7 @@ nsresult nsStandardURL::SetHost(const nsACString& input) {
return NS_ERROR_MALFORMED_URI; return NS_ERROR_MALFORMED_URI;
} }
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
InvalidateCache(); InvalidateCache();
uint32_t len; uint32_t len;
@ -2092,6 +2108,8 @@ nsresult nsStandardURL::SetPort(int32_t port) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
InvalidateCache(); InvalidateCache();
if (port == mDefaultPort) { if (port == mDefaultPort) {
port = -1; port = -1;
@ -2116,6 +2134,8 @@ void nsStandardURL::ReplacePortInSpec(int32_t aNewPort) {
"Caller should check its passed-in value and pass -1 instead of " "Caller should check its passed-in value and pass -1 instead of "
"mDefaultPort, to avoid encoding default port into mSpec"); "mDefaultPort, to avoid encoding default port into mSpec");
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
// Create the (possibly empty) string that we're planning to replace: // Create the (possibly empty) string that we're planning to replace:
nsAutoCString buf; nsAutoCString buf;
if (mPort != -1) { if (mPort != -1) {
@ -2146,6 +2166,7 @@ void nsStandardURL::ReplacePortInSpec(int32_t aNewPort) {
nsresult nsStandardURL::SetPathQueryRef(const nsACString& input) { nsresult nsStandardURL::SetPathQueryRef(const nsACString& input) {
const nsPromiseFlatCString& path = PromiseFlatCString(input); const nsPromiseFlatCString& path = PromiseFlatCString(input);
LOG(("nsStandardURL::SetPathQueryRef [path=%s]\n", path.get())); LOG(("nsStandardURL::SetPathQueryRef [path=%s]\n", path.get()));
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
InvalidateCache(); InvalidateCache();
@ -2337,6 +2358,8 @@ nsresult nsStandardURL::CloneInternal(
nsresult nsStandardURL::CopyMembers( nsresult nsStandardURL::CopyMembers(
nsStandardURL* source, nsStandardURL::RefHandlingEnum refHandlingMode, nsStandardURL* source, nsStandardURL::RefHandlingEnum refHandlingMode,
const nsACString& newRef, bool copyCached) { const nsACString& newRef, bool copyCached) {
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
mSpec = source->mSpec; mSpec = source->mSpec;
mDefaultPort = source->mDefaultPort; mDefaultPort = source->mDefaultPort;
mPort = source->mPort; mPort = source->mPort;
@ -2760,6 +2783,7 @@ nsresult nsStandardURL::SetFilePath(const nsACString& input) {
const char* filepath = flat.get(); const char* filepath = flat.get();
LOG(("nsStandardURL::SetFilePath [filepath=%s]\n", filepath)); LOG(("nsStandardURL::SetFilePath [filepath=%s]\n", filepath));
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
// if there isn't a filepath, then there can't be anything // if there isn't a filepath, then there can't be anything
// after the path either. this url is likely uninitialized. // after the path either. this url is likely uninitialized.
@ -2852,6 +2876,7 @@ nsresult nsStandardURL::SetQueryWithEncoding(const nsACString& input,
const char* query = flat.get(); const char* query = flat.get();
LOG(("nsStandardURL::SetQuery [query=%s]\n", query)); LOG(("nsStandardURL::SetQuery [query=%s]\n", query));
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
if (IsUTFEncoding(encoding)) { if (IsUTFEncoding(encoding)) {
encoding = nullptr; encoding = nullptr;
@ -2933,6 +2958,7 @@ nsresult nsStandardURL::SetRef(const nsACString& input) {
const char* ref = flat.get(); const char* ref = flat.get();
LOG(("nsStandardURL::SetRef [ref=%s]\n", ref)); LOG(("nsStandardURL::SetRef [ref=%s]\n", ref));
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
if (mPath.mLen < 0) { if (mPath.mLen < 0) {
return SetPathQueryRef(flat); return SetPathQueryRef(flat);
@ -2999,6 +3025,7 @@ nsresult nsStandardURL::SetFileNameInternal(const nsACString& input) {
const char* filename = flat.get(); const char* filename = flat.get();
LOG(("nsStandardURL::SetFileNameInternal [filename=%s]\n", filename)); LOG(("nsStandardURL::SetFileNameInternal [filename=%s]\n", filename));
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
if (mPath.mLen < 0) { if (mPath.mLen < 0) {
return SetPathQueryRef(flat); return SetPathQueryRef(flat);
@ -3091,6 +3118,7 @@ nsresult nsStandardURL::SetFileNameInternal(const nsACString& input) {
} }
nsresult nsStandardURL::SetFileBaseNameInternal(const nsACString& input) { nsresult nsStandardURL::SetFileBaseNameInternal(const nsACString& input) {
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
nsAutoCString extension; nsAutoCString extension;
nsresult rv = GetFileExtension(extension); nsresult rv = GetFileExtension(extension);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -3106,6 +3134,7 @@ nsresult nsStandardURL::SetFileBaseNameInternal(const nsACString& input) {
} }
nsresult nsStandardURL::SetFileExtensionInternal(const nsACString& input) { nsresult nsStandardURL::SetFileExtensionInternal(const nsACString& input) {
auto onExitGuard = MakeScopeExit([&] { SanityCheck(); });
nsAutoCString newFileName; nsAutoCString newFileName;
nsresult rv = GetFileBaseName(newFileName); nsresult rv = GetFileBaseName(newFileName);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);

View File

@ -257,8 +257,8 @@ class nsStandardURL : public nsIFileURL,
void FindHostLimit(nsACString::const_iterator& aStart, void FindHostLimit(nsACString::const_iterator& aStart,
nsACString::const_iterator& aEnd); nsACString::const_iterator& aEnd);
// Asserts that the URLSegment has sane values // Asserts that the URL has sane values
static void SanityCheck(const URLSegment&, const nsCString&); void SanityCheck();
// mSpec contains the normalized version of the URL spec (UTF-8 encoded). // mSpec contains the normalized version of the URL spec (UTF-8 encoded).
nsCString mSpec; nsCString mSpec;