mirror of
https://github.com/classilla/tenfourfox.git
synced 2025-04-12 16:37:15 +00:00
#632: M1249352(remaining) M1358297(backbugs) M1369317(pp1,3,4) M1426996
This commit is contained in:
parent
c1a28532cf
commit
1eab6170b1
@ -192,27 +192,23 @@ NS_IMETHODIMP
|
||||
nsSimpleURI::SetSpec(const nsACString &aSpec)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
// filter out unexpected chars "\r\n\t" if necessary
|
||||
nsAutoCString filteredSpec;
|
||||
net_FilterURIString(aSpec, filteredSpec);
|
||||
const char* specPtr = filteredSpec.get();
|
||||
int32_t specLen = filteredSpec.Length();
|
||||
|
||||
// nsSimpleURI currently restricts the charset to US-ASCII
|
||||
nsAutoCString spec;
|
||||
NS_EscapeURL(specPtr, specLen, esc_OnlyNonASCII|esc_AlwaysCopy, spec);
|
||||
|
||||
int32_t colonPos = spec.FindChar(':');
|
||||
if (colonPos < 0 || !net_IsValidScheme(spec.get(), colonPos))
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
||||
mScheme.Truncate();
|
||||
mozilla::DebugOnly<int32_t> n = spec.Left(mScheme, colonPos);
|
||||
NS_ASSERTION(n == colonPos, "Left failed");
|
||||
nsresult rv = net_ExtractURLScheme(aSpec, mScheme);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
ToLowerCase(mScheme);
|
||||
|
||||
nsAutoCString spec;
|
||||
rv = net_FilterAndEscapeURI(aSpec, esc_OnlyNonASCII, spec);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int32_t colonPos = spec.FindChar(':');
|
||||
MOZ_ASSERT(colonPos != kNotFound, "A colon should be in this string");
|
||||
// This sets both mPath and mRef.
|
||||
// If changed, see bug 1369317, especially part 2 -- Cameron
|
||||
return SetPath(Substring(spec, colonPos + 1));
|
||||
}
|
||||
|
||||
@ -383,7 +379,13 @@ nsSimpleURI::SetRef(const nsACString &aRef)
|
||||
{
|
||||
NS_ENSURE_STATE(mMutable);
|
||||
|
||||
if (aRef.IsEmpty()) {
|
||||
nsAutoCString ref;
|
||||
nsresult rv = NS_EscapeURL(aRef, esc_OnlyNonASCII, ref, fallible);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (ref.IsEmpty()) {
|
||||
// Empty string means to remove ref completely.
|
||||
mIsRefValid = false;
|
||||
mRef.Truncate(); // invariant: mRef should be empty when it's not valid
|
||||
@ -513,12 +515,11 @@ nsSimpleURI::Resolve(const nsACString &relativePath, nsACString &result)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleURI::GetAsciiSpec(nsACString &result)
|
||||
nsSimpleURI::GetAsciiSpec(nsACString &aResult)
|
||||
{
|
||||
nsAutoCString buf;
|
||||
nsresult rv = GetSpec(buf);
|
||||
nsresult rv = GetSpec(aResult);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_EscapeURL(buf, esc_OnlyNonASCII|esc_AlwaysCopy, result);
|
||||
MOZ_ASSERT(IsASCII(aResult), "The spec should be ASCII");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include "nsASCIIMask.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIURLParser.h"
|
||||
@ -18,6 +19,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "prnetdb.h"
|
||||
#include "mozilla/Tokenizer.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
#include "mozilla-config.h"
|
||||
#include "plvmx.h"
|
||||
@ -543,7 +545,7 @@ net_ExtractURLScheme(const nsACString &inURI,
|
||||
}
|
||||
|
||||
p.Claim(scheme);
|
||||
scheme.StripChars("\r\n\t");
|
||||
scheme.StripTaggedASCII(ASCIIMask::MaskCRLFTab());
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
@ -615,8 +617,6 @@ net_IsAbsoluteURL(const nsACString& uri)
|
||||
void
|
||||
net_FilterURIString(const nsACString& input, nsACString& result)
|
||||
{
|
||||
const char kCharsToStrip[] = "\r\n\t";
|
||||
|
||||
result.Truncate();
|
||||
auto start = input.BeginReading();
|
||||
auto end = input.EndReading();
|
||||
@ -630,9 +630,14 @@ net_FilterURIString(const nsACString& input, nsACString& result)
|
||||
charFilter).base();
|
||||
|
||||
// Check if chars need to be stripped.
|
||||
auto itr = std::find_first_of(
|
||||
newStart, newEnd, std::begin(kCharsToStrip), std::end(kCharsToStrip));
|
||||
const bool needsStrip = itr != newEnd;
|
||||
bool needsStrip = false;
|
||||
const ASCIIMaskArray& mask = ASCIIMask::MaskCRLFTab();
|
||||
for (auto itr = start; itr != end; ++itr) {
|
||||
if (ASCIIMask::IsMasked(mask, *itr)) {
|
||||
needsStrip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Just use the passed in string rather than creating new copies if no
|
||||
// changes are necessary.
|
||||
@ -643,10 +648,31 @@ net_FilterURIString(const nsACString& input, nsACString& result)
|
||||
|
||||
result.Assign(Substring(newStart, newEnd));
|
||||
if (needsStrip) {
|
||||
result.StripChars(kCharsToStrip);
|
||||
result.StripTaggedASCII(mask);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
net_FilterAndEscapeURI(const nsACString& aInput, uint32_t aFlags, nsACString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
|
||||
auto start = aInput.BeginReading();
|
||||
auto end = aInput.EndReading();
|
||||
|
||||
// Trim off leading and trailing invalid chars.
|
||||
auto charFilter = [](char c) { return static_cast<uint8_t>(c) > 0x20; };
|
||||
auto newStart = std::find_if(start, end, charFilter);
|
||||
auto newEnd = std::find_if(
|
||||
std::reverse_iterator<decltype(end)>(end),
|
||||
std::reverse_iterator<decltype(newStart)>(newStart),
|
||||
charFilter).base();
|
||||
|
||||
const ASCIIMaskArray& mask = ASCIIMask::MaskCRLFTab();
|
||||
return NS_EscapeAndFilterURL(Substring(newStart, newEnd), aFlags,
|
||||
&mask, aResult, fallible);
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
bool
|
||||
net_NormalizeFileURL(const nsACString &aURL, nsCString &aResultBuf)
|
||||
|
@ -115,6 +115,18 @@ inline bool net_IsValidScheme(const nsAFlatCString &scheme)
|
||||
*/
|
||||
void net_FilterURIString(const nsACString& input, nsACString& result);
|
||||
|
||||
/**
|
||||
* This function performs character stripping just like net_FilterURIString,
|
||||
* with the added benefit of also performing percent escaping of dissallowed
|
||||
* characters, all in one pass. Saving one pass is very important when operating
|
||||
* on really large strings.
|
||||
*
|
||||
* @param aInput the URL spec we want to filter
|
||||
* @param aFlags the flags which control which characters we escape
|
||||
* @param aResult the out param to write to if filtering happens
|
||||
*/
|
||||
nsresult net_FilterAndEscapeURI(const nsACString& aInput, uint32_t aFlags, nsACString& aResult);
|
||||
|
||||
#if defined(XP_WIN)
|
||||
/**
|
||||
* On Win32 and OS/2 system's a back-slash in a file:// URL is equivalent to a
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsTArray.h"
|
||||
#include "nsCRT.h"
|
||||
#include "plstr.h"
|
||||
#include "nsASCIIMask.h"
|
||||
|
||||
#include "mozilla-config.h"
|
||||
#include "plvmx.h"
|
||||
@ -381,10 +382,23 @@ static uint16_t dontNeedEscape(uint16_t aChar, uint32_t aFlags)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Templated helper for URL escaping a portion of a string.
|
||||
*
|
||||
* @param aPart The pointer to the beginning of the portion of the string to
|
||||
* escape.
|
||||
* @param aPartLen The length of the string to escape.
|
||||
* @param aFlags Flags used to configure escaping. @see EscapeMask
|
||||
* @param aResult String that has the URL escaped portion appended to. Only
|
||||
* altered if the string is URL escaped or |esc_AlwaysCopy| is specified.
|
||||
* @param aDidAppend Indicates whether or not data was appended to |aResult|.
|
||||
* @return NS_ERROR_INVALID_ARG, NS_ERROR_OUT_OF_MEMORY on failure.
|
||||
*/
|
||||
template<class T>
|
||||
static bool
|
||||
static nsresult
|
||||
T_EscapeURL(const typename T::char_type* aPart, size_t aPartLen,
|
||||
uint32_t aFlags, T& aResult)
|
||||
uint32_t aFlags, const ASCIIMaskArray* aFilterMask,
|
||||
T& aResult, bool& aDidAppend)
|
||||
{
|
||||
typedef nsCharTraits<typename T::char_type> traits;
|
||||
typedef typename traits::unsigned_char_type unsigned_char_type;
|
||||
@ -393,7 +407,7 @@ T_EscapeURL(const typename T::char_type* aPart, size_t aPartLen,
|
||||
|
||||
if (!aPart) {
|
||||
NS_NOTREACHED("null pointer");
|
||||
return false;
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
bool forced = !!(aFlags & esc_Forced);
|
||||
@ -411,6 +425,19 @@ T_EscapeURL(const typename T::char_type* aPart, size_t aPartLen,
|
||||
for (size_t i = 0; i < aPartLen; ++i) {
|
||||
unsigned_char_type c = *src++;
|
||||
|
||||
// If there is a filter, we wish to skip any characters which match it.
|
||||
// This is needed so we don't perform an extra pass just to extract the
|
||||
// filtered characters.
|
||||
if (aFilterMask && ASCIIMask::IsMasked(*aFilterMask, c)) {
|
||||
if (!writing) {
|
||||
if (!aResult.Append(aPart, i, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
writing = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the char has not to be escaped or whatever follows % is
|
||||
// a valid escaped string, just copy the char.
|
||||
//
|
||||
@ -437,7 +464,9 @@ T_EscapeURL(const typename T::char_type* aPart, size_t aPartLen,
|
||||
}
|
||||
} else { /* do the escape magic */
|
||||
if (!writing) {
|
||||
aResult.Append(aPart, i);
|
||||
if (!aResult.Append(aPart, i, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
writing = true;
|
||||
}
|
||||
uint32_t len = ::AppendPercentHex(tempBuffer + tempBufferPos, c);
|
||||
@ -448,16 +477,21 @@ T_EscapeURL(const typename T::char_type* aPart, size_t aPartLen,
|
||||
// Flush the temp buffer if it doesnt't have room for another encoded char.
|
||||
if (tempBufferPos >= mozilla::ArrayLength(tempBuffer) - ENCODE_MAX_LEN) {
|
||||
NS_ASSERTION(writing, "should be writing");
|
||||
aResult.Append(tempBuffer, tempBufferPos);
|
||||
if (!aResult.Append(tempBuffer, tempBufferPos, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
tempBufferPos = 0;
|
||||
}
|
||||
|
||||
previousIsNonASCII = (c > 0x7f);
|
||||
}
|
||||
if (writing) {
|
||||
aResult.Append(tempBuffer, tempBufferPos);
|
||||
if (!aResult.Append(tempBuffer, tempBufferPos, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return writing;
|
||||
aDidAppend = writing;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -467,13 +501,66 @@ NS_EscapeURL(const char* aPart, int32_t aPartLen, uint32_t aFlags,
|
||||
if (aPartLen < 0) {
|
||||
aPartLen = strlen(aPart);
|
||||
}
|
||||
return T_EscapeURL(aPart, aPartLen, aFlags, aResult);
|
||||
|
||||
bool result = false;
|
||||
nsresult rv = T_EscapeURL(aPart, aPartLen, aFlags, nullptr, aResult, result);
|
||||
if (NS_FAILED(rv)) {
|
||||
::NS_ABORT_OOM(aResult.Length() * sizeof(nsACString::char_type));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_EscapeURL(const nsCSubstring& aStr, uint32_t aFlags, nsCSubstring& aResult,
|
||||
const mozilla::fallible_t&)
|
||||
{
|
||||
bool appended = false;
|
||||
nsresult rv = T_EscapeURL(aStr.Data(), aStr.Length(), aFlags, nullptr, aResult, appended);
|
||||
if (NS_FAILED(rv)) {
|
||||
aResult.Truncate();
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!appended) {
|
||||
if (!aResult.Assign(aStr, fallible)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_EscapeAndFilterURL(const nsACString& aStr, uint32_t aFlags,
|
||||
const ASCIIMaskArray* aFilterMask,
|
||||
nsACString& aResult, const mozilla::fallible_t&)
|
||||
{
|
||||
bool appended = false;
|
||||
nsresult rv = T_EscapeURL(aStr.Data(), aStr.Length(), aFlags, aFilterMask, aResult, appended);
|
||||
if (NS_FAILED(rv)) {
|
||||
aResult.Truncate();
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!appended) {
|
||||
aResult = aStr;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
const nsSubstring&
|
||||
NS_EscapeURL(const nsSubstring& aStr, uint32_t aFlags, nsSubstring& aResult)
|
||||
{
|
||||
if (T_EscapeURL<nsSubstring>(aStr.Data(), aStr.Length(), aFlags, aResult)) {
|
||||
bool result = false;
|
||||
nsresult rv = T_EscapeURL<nsSubstring>(aStr.Data(), aStr.Length(), aFlags, nullptr, aResult, result);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
::NS_ABORT_OOM(aResult.Length() * sizeof(nsSubstring::char_type));
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return aResult;
|
||||
}
|
||||
return aStr;
|
||||
|
@ -155,6 +155,28 @@ NS_EscapeURL(const nsCSubstring& aStr, uint32_t aFlags, nsCSubstring& aResult)
|
||||
}
|
||||
return aStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallible version of NS_EscapeURL. On success aResult will point to either
|
||||
* the original string or an escaped copy.
|
||||
*/
|
||||
nsresult
|
||||
NS_EscapeURL(const nsCSubstring& aStr, uint32_t aFlags, nsCSubstring& aResult,
|
||||
const mozilla::fallible_t&);
|
||||
|
||||
// Forward declaration for nsASCIIMask.h
|
||||
typedef std::array<bool, 128> ASCIIMaskArray;
|
||||
|
||||
/**
|
||||
* The same as NS_EscapeURL, except it also filters out characters that match
|
||||
* aFilterMask.
|
||||
*/
|
||||
nsresult
|
||||
NS_EscapeAndFilterURL(const nsACString& aStr, uint32_t aFlags,
|
||||
const ASCIIMaskArray* aFilterMask,
|
||||
nsACString& aResult, const mozilla::fallible_t&);
|
||||
|
||||
|
||||
inline const nsCSubstring&
|
||||
NS_UnescapeURL(const nsCSubstring& aStr, uint32_t aFlags, nsCSubstring& aResult)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user