зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1369317 - Filter and escape URI string in only one pass r=mcmanus
MozReview-Commit-ID: KU4C4cS3jZC --HG-- extra : rebase_source : 4995b4d8a133b8568af5b130be2077ee90f8b4e4
This commit is contained in:
Родитель
c499c0ebcb
Коммит
97a44a506c
|
@ -297,15 +297,10 @@ nsSimpleURI::SetSpec(const nsACString &aSpec)
|
||||||
}
|
}
|
||||||
ToLowerCase(mScheme);
|
ToLowerCase(mScheme);
|
||||||
|
|
||||||
// filter out unexpected chars "\r\n\t" if necessary
|
|
||||||
nsAutoCString filteredSpec;
|
|
||||||
net_FilterURIString(aSpec, filteredSpec);
|
|
||||||
|
|
||||||
// nsSimpleURI currently restricts the charset to US-ASCII
|
|
||||||
nsAutoCString spec;
|
nsAutoCString spec;
|
||||||
rv = NS_EscapeURL(filteredSpec, esc_OnlyNonASCII, spec, fallible);
|
rv = net_FilterAndEscapeURI(aSpec, esc_OnlyNonASCII, spec);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t colonPos = spec.FindChar(':');
|
int32_t colonPos = spec.FindChar(':');
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "prnetdb.h"
|
#include "prnetdb.h"
|
||||||
#include "mozilla/Tokenizer.h"
|
#include "mozilla/Tokenizer.h"
|
||||||
|
#include "nsEscape.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
|
@ -628,6 +629,26 @@ net_FilterURIString(const nsACString& input, nsACString& result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
#if defined(XP_WIN)
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -115,6 +115,18 @@ inline bool net_IsValidScheme(const nsCString& scheme)
|
||||||
*/
|
*/
|
||||||
void net_FilterURIString(const nsACString& input, nsACString& result);
|
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)
|
#if defined(XP_WIN)
|
||||||
/**
|
/**
|
||||||
* On Win32 and OS/2 system's a back-slash in a file:// URL is equivalent to a
|
* 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 "nsTArray.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "plstr.h"
|
#include "plstr.h"
|
||||||
|
#include "nsASCIIMask.h"
|
||||||
|
|
||||||
static const char hexCharsUpper[] = "0123456789ABCDEF";
|
static const char hexCharsUpper[] = "0123456789ABCDEF";
|
||||||
static const char hexCharsUpperLower[] = "0123456789ABCDEFabcdef";
|
static const char hexCharsUpperLower[] = "0123456789ABCDEFabcdef";
|
||||||
|
@ -382,7 +383,8 @@ static uint16_t dontNeedEscape(uint16_t aChar, uint32_t aFlags)
|
||||||
template<class T>
|
template<class T>
|
||||||
static nsresult
|
static nsresult
|
||||||
T_EscapeURL(const typename T::char_type* aPart, size_t aPartLen,
|
T_EscapeURL(const typename T::char_type* aPart, size_t aPartLen,
|
||||||
uint32_t aFlags, T& aResult, bool& aDidAppend)
|
uint32_t aFlags, const ASCIIMaskArray* aFilterMask,
|
||||||
|
T& aResult, bool& aDidAppend)
|
||||||
{
|
{
|
||||||
typedef nsCharTraits<typename T::char_type> traits;
|
typedef nsCharTraits<typename T::char_type> traits;
|
||||||
typedef typename traits::unsigned_char_type unsigned_char_type;
|
typedef typename traits::unsigned_char_type unsigned_char_type;
|
||||||
|
@ -409,6 +411,19 @@ T_EscapeURL(const typename T::char_type* aPart, size_t aPartLen,
|
||||||
for (size_t i = 0; i < aPartLen; ++i) {
|
for (size_t i = 0; i < aPartLen; ++i) {
|
||||||
unsigned_char_type c = *src++;
|
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
|
// if the char has not to be escaped or whatever follows % is
|
||||||
// a valid escaped string, just copy the char.
|
// a valid escaped string, just copy the char.
|
||||||
//
|
//
|
||||||
|
@ -474,7 +489,7 @@ NS_EscapeURL(const char* aPart, int32_t aPartLen, uint32_t aFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
nsresult rv = T_EscapeURL(aPart, aPartLen, aFlags, aResult, result);
|
nsresult rv = T_EscapeURL(aPart, aPartLen, aFlags, nullptr, aResult, result);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
::NS_ABORT_OOM(aResult.Length() * sizeof(nsACString::char_type));
|
::NS_ABORT_OOM(aResult.Length() * sizeof(nsACString::char_type));
|
||||||
}
|
}
|
||||||
|
@ -487,7 +502,26 @@ NS_EscapeURL(const nsACString& aStr, uint32_t aFlags, nsACString& aResult,
|
||||||
const mozilla::fallible_t&)
|
const mozilla::fallible_t&)
|
||||||
{
|
{
|
||||||
bool appended = false;
|
bool appended = false;
|
||||||
nsresult rv = T_EscapeURL(aStr.Data(), aStr.Length(), aFlags, aResult, appended);
|
nsresult rv = T_EscapeURL(aStr.Data(), aStr.Length(), aFlags, nullptr, aResult, appended);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
aResult.Truncate();
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!appended) {
|
||||||
|
aResult = aStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
if (NS_FAILED(rv)) {
|
||||||
aResult.Truncate();
|
aResult.Truncate();
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -504,7 +538,7 @@ const nsAString&
|
||||||
NS_EscapeURL(const nsAString& aStr, uint32_t aFlags, nsAString& aResult)
|
NS_EscapeURL(const nsAString& aStr, uint32_t aFlags, nsAString& aResult)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
nsresult rv = T_EscapeURL<nsAString>(aStr.Data(), aStr.Length(), aFlags, aResult, result);
|
nsresult rv = T_EscapeURL<nsAString>(aStr.Data(), aStr.Length(), aFlags, nullptr, aResult, result);
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
::NS_ABORT_OOM(aResult.Length() * sizeof(nsAString::char_type));
|
::NS_ABORT_OOM(aResult.Length() * sizeof(nsAString::char_type));
|
||||||
|
|
|
@ -169,6 +169,19 @@ nsresult
|
||||||
NS_EscapeURL(const nsACString& aStr, uint32_t aFlags, nsACString& aResult,
|
NS_EscapeURL(const nsACString& aStr, uint32_t aFlags, nsACString& aResult,
|
||||||
const mozilla::fallible_t&);
|
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 nsACString&
|
inline const nsACString&
|
||||||
NS_UnescapeURL(const nsACString& aStr, uint32_t aFlags, nsACString& aResult)
|
NS_UnescapeURL(const nsACString& aStr, uint32_t aFlags, nsACString& aResult)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче