diff options
Diffstat (limited to 'netwerk/base/nsStandardURL.cpp')
-rw-r--r-- | netwerk/base/nsStandardURL.cpp | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index 1866c10379..3d77093004 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -315,6 +315,46 @@ DumpLeakedURLs::~DumpLeakedURLs() } #endif +bool nsStandardURL::IsValid() { + auto checkSegment = [&](const nsStandardURL::URLSegment& aSeg) { + // Bad value + if (NS_WARN_IF(aSeg.mLen < -1)) { + return false; + } + if (aSeg.mLen == -1) { + return true; + } + + // Position outside of string + if (NS_WARN_IF(aSeg.mPos + aSeg.mLen > mSpec.Length())) { + return false; + } + + // Overflow + if (NS_WARN_IF(aSeg.mPos + aSeg.mLen < aSeg.mPos)) { + return false; + } + + return true; + }; + + bool allSegmentsValid = checkSegment(mScheme) && checkSegment(mAuthority) && + checkSegment(mUsername) && checkSegment(mPassword) && + checkSegment(mHost) && checkSegment(mPath) && + checkSegment(mFilepath) && checkSegment(mDirectory) && + checkSegment(mBasename) && checkSegment(mExtension) && + checkSegment(mQuery) && checkSegment(mRef); + if (!allSegmentsValid) { + return false; + } + + if (mScheme.mPos != 0) { + return false; + } + + return true; +} + void nsStandardURL::InitGlobalObjects() { @@ -2752,8 +2792,8 @@ nsStandardURL::SetFilePath(const nsACString &input) mSpec.Cut(mPath.mPos + 1, mFilepath.mLen - 1); // left shift query, and ref ShiftFromQuery(1 - mFilepath.mLen); - // One character for '/', and if we have a query or ref we add their
- // length and one extra for each '?' or '#' characters
+ // One character for '/', and if we have a query or ref we add their + // length and one extra for each '?' or '#' characters mPath.mLen = 1 + (mQuery.mLen >= 0 ? (mQuery.mLen + 1) : 0) + (mRef.mLen >= 0 ? (mRef.mLen + 1) : 0); // these contain only a '/' @@ -3518,6 +3558,10 @@ nsStandardURL::Deserialize(const URIParams& aParams) return false; } + // If we exit early, make sure to clear the URL so we don't fail the sanity + // check in the destructor + auto clearOnExit = MakeScopeExit([&] { Clear(); }); + const StandardURLParams& params = aParams.get_StandardURLParams(); mURLType = params.urlType(); @@ -3565,7 +3609,7 @@ nsStandardURL::Deserialize(const URIParams& aParams) mSupportsFileURL = params.supportsFileURL(); mHostEncoding = params.hostEncoding(); - // Some sanity checks + // Some segment sanity checks NS_ENSURE_TRUE(mScheme.mPos == 0, false); NS_ENSURE_TRUE(mScheme.mLen > 0, false); // Make sure scheme is followed by :// (3 characters) @@ -3577,6 +3621,13 @@ nsStandardURL::Deserialize(const URIParams& aParams) NS_ENSURE_TRUE(mQuery.mLen == -1 || mSpec.CharAt(mQuery.mPos - 1) == '?', false); NS_ENSURE_TRUE(mRef.mLen == -1 || mSpec.CharAt(mRef.mPos - 1) == '#', false); + // Sanity-check the result + if (!IsValid()) { + return false; + } + + clearOnExit.release(); + // mSpecEncoding and mHostA are just caches that can be recovered as needed. return true; } |