Bug 1272298 - nsFormSubmission should support "\0" input string, r=smaug

This commit is contained in:
Andrea Marchesini 2016-05-13 22:48:03 +02:00
Родитель 0465f58516
Коммит 6f820b5dd7
4 изменённых файлов: 67 добавлений и 46 удалений

Просмотреть файл

@ -117,7 +117,7 @@ protected:
* @param aEncoded the encoded string [OUT]
* @throws NS_ERROR_OUT_OF_MEMORY if we run out of memory
*/
nsresult URLEncode(const nsAString& aStr, nsCString& aEncoded);
nsresult URLEncode(const nsAString& aStr, nsACString& aEncoded);
private:
/**
@ -363,23 +363,28 @@ nsFSURLEncoded::GetEncodedSubmission(nsIURI* aURI,
// i18n helper routines
nsresult
nsFSURLEncoded::URLEncode(const nsAString& aStr, nsCString& aEncoded)
nsFSURLEncoded::URLEncode(const nsAString& aStr, nsACString& aEncoded)
{
// convert to CRLF breaks
int32_t convertedBufLength = 0;
char16_t* convertedBuf =
nsLinebreakConverter::ConvertUnicharLineBreaks(PromiseFlatString(aStr).get(),
nsLinebreakConverter::ConvertUnicharLineBreaks(aStr.BeginReading(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakNet);
nsLinebreakConverter::eLinebreakNet,
aStr.Length(),
&convertedBufLength);
NS_ENSURE_TRUE(convertedBuf, NS_ERROR_OUT_OF_MEMORY);
nsAutoString convertedString;
convertedString.Adopt(convertedBuf, convertedBufLength);
nsAutoCString encodedBuf;
nsresult rv = EncodeVal(nsDependentString(convertedBuf), encodedBuf, false);
free(convertedBuf);
nsresult rv = EncodeVal(convertedString, encodedBuf, false);
NS_ENSURE_SUCCESS(rv, rv);
char* escapedBuf = nsEscape(encodedBuf.get(), url_XPAlphas);
NS_ENSURE_TRUE(escapedBuf, NS_ERROR_OUT_OF_MEMORY);
aEncoded.Adopt(escapedBuf);
if (NS_WARN_IF(!NS_Escape(encodedBuf, aEncoded, url_XPAlphas))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}

Просмотреть файл

@ -2124,7 +2124,7 @@ nsWebBrowserPersist::MakeFilenameFromURI(nsIURI *aURI, nsString &aFilename)
url->GetFileName(nameFromURL);
if (mPersistFlags & PERSIST_FLAGS_DONT_CHANGE_FILENAMES)
{
fileName.AssignWithConversion(NS_UnescapeURL(nameFromURL).get());
fileName.AssignWithConversion(NS_UnescapeURL(nameFromURL).BeginReading());
aFilename = fileName;
return NS_OK;
}

Просмотреть файл

@ -73,21 +73,32 @@ AppendPercentHex(char16_t* aBuffer, char16_t aChar)
}
//----------------------------------------------------------------------------------------
static char*
nsEscapeCount(const char* aStr, nsEscapeMask aFlags, size_t* aOutLen)
char*
nsEscape(const char* aStr, nsEscapeMask aFlags)
//----------------------------------------------------------------------------------------
{
if (!aStr) {
return 0;
return nullptr;
}
return nsEscapeWithLength(aStr, strlen(aStr), nullptr, aFlags);
}
//----------------------------------------------------------------------------------------
char*
nsEscapeWithLength(const char* aStr, size_t aLength, size_t* aOutputLength,
nsEscapeMask aFlags)
//----------------------------------------------------------------------------------------
{
if (!aStr) {
return nullptr;
}
size_t len = 0;
size_t charsToEscape = 0;
const unsigned char* src = (const unsigned char*)aStr;
while (*src) {
len++;
if (!IS_OK(*src++)) {
for (size_t i = 0; i < aLength; ++i) {
if (!IS_OK(src[i])) {
charsToEscape++;
}
}
@ -95,29 +106,29 @@ nsEscapeCount(const char* aStr, nsEscapeMask aFlags, size_t* aOutLen)
// calculate how much memory should be allocated
// original length + 2 bytes for each escaped character + terminating '\0'
// do the sum in steps to check for overflow
size_t dstSize = len + 1 + charsToEscape;
if (dstSize <= len) {
return 0;
size_t dstSize = aLength + 1 + charsToEscape;
if (dstSize <= aLength) {
return nullptr;
}
dstSize += charsToEscape;
if (dstSize < len) {
return 0;
if (dstSize < aLength) {
return nullptr;
}
// fail if we need more than 4GB
if (dstSize > UINT32_MAX) {
return 0;
return nullptr;
}
char* result = (char*)moz_xmalloc(dstSize);
if (!result) {
return 0;
return nullptr;
}
unsigned char* dst = (unsigned char*)result;
src = (const unsigned char*)aStr;
if (aFlags == url_XPAlphas) {
for (size_t i = 0; i < len; ++i) {
for (size_t i = 0; i < aLength; ++i) {
unsigned char c = *src++;
if (IS_OK(c)) {
*dst++ = c;
@ -130,7 +141,7 @@ nsEscapeCount(const char* aStr, nsEscapeMask aFlags, size_t* aOutLen)
}
}
} else {
for (size_t i = 0; i < len; ++i) {
for (size_t i = 0; i < aLength; ++i) {
unsigned char c = *src++;
if (IS_OK(c)) {
*dst++ = c;
@ -143,21 +154,11 @@ nsEscapeCount(const char* aStr, nsEscapeMask aFlags, size_t* aOutLen)
}
*dst = '\0'; /* tack on eos */
if (aOutLen) {
*aOutLen = dst - (unsigned char*)result;
if (aOutputLength) {
*aOutputLength = dst - (unsigned char*)result;
}
return result;
}
//----------------------------------------------------------------------------------------
char*
nsEscape(const char* aStr, nsEscapeMask aFlags)
//----------------------------------------------------------------------------------------
{
if (!aStr) {
return nullptr;
}
return nsEscapeCount(aStr, aFlags, nullptr);
return result;
}
//----------------------------------------------------------------------------------------

Просмотреть файл

@ -31,8 +31,21 @@ extern "C" {
/**
* Escape the given string according to mask
* @param str The string to escape
* @param mask How to escape the string
* @param aSstr The string to escape
* @param aLength The length of the string to escape
* @param aOutputLen A pointer that will be used to store the length of the
* output string, if not null
* @param aMask How to escape the string
* @return A newly allocated escaped string that must be free'd with
* nsCRT::free, or null on failure
*/
char* nsEscapeWithLength(const char* aStr, size_t aLength, size_t* aOutputLen,
nsEscapeMask aMask);
/**
* Escape the given string according to mask
* @param aStr The string to escape
* @param aMask How to escape the string
* @return A newly allocated escaped string that must be free'd with
* nsCRT::free, or null on failure
*/
@ -184,22 +197,24 @@ NS_EscapeURL(const nsAFlatString& aStr, const nsTArray<char16_t>& aForbidden,
* on out of memory. To reverse this function, use NS_UnescapeURL.
*/
inline bool
NS_Escape(const nsCString& aOriginal, nsCString& aEscaped,
NS_Escape(const nsACString& aOriginal, nsACString& aEscaped,
nsEscapeMask aMask)
{
char* esc = nsEscape(aOriginal.get(), aMask);
size_t escLen = 0;
char* esc = nsEscapeWithLength(aOriginal.BeginReading(), aOriginal.Length(),
&escLen, aMask);
if (! esc) {
return false;
}
aEscaped.Adopt(esc);
aEscaped.Adopt(esc, escLen);
return true;
}
/**
* Inline unescape of mutable string object.
*/
inline nsCString&
NS_UnescapeURL(nsCString& aStr)
inline nsACString&
NS_UnescapeURL(nsACString& aStr)
{
aStr.SetLength(nsUnescapeCount(aStr.BeginWriting()));
return aStr;