mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-06 07:48:38 +09:00
[network] Add some sanity checks to deserialized nsStandardURLs
Note: C++ lambda expressions are actually useful for once.
This commit is contained in:
parent
0a42897070
commit
43f7d3e27a
3 changed files with 108 additions and 3 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue