mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-24 16:17:29 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
de0b4ac202
15 changed files with 437 additions and 77 deletions
|
|
@ -7058,16 +7058,26 @@ nsContentUtils::HasDistributedChildren(nsIContent* aContent)
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader)
|
nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader,
|
||||||
|
const nsACString& aValue)
|
||||||
{
|
{
|
||||||
if (IsForbiddenSystemRequestHeader(aHeader)) {
|
if (IsForbiddenSystemRequestHeader(aHeader)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return StringBeginsWith(aHeader, NS_LITERAL_CSTRING("proxy-"),
|
if ((nsContentUtils::IsOverrideMethodHeader(aHeader) &&
|
||||||
|
nsContentUtils::ContainsForbiddenMethod(aValue))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringBeginsWith(aHeader, NS_LITERAL_CSTRING("proxy-"),
|
||||||
nsCaseInsensitiveCStringComparator()) ||
|
nsCaseInsensitiveCStringComparator()) ||
|
||||||
StringBeginsWith(aHeader, NS_LITERAL_CSTRING("sec-"),
|
StringBeginsWith(aHeader, NS_LITERAL_CSTRING("sec-"),
|
||||||
nsCaseInsensitiveCStringComparator());
|
nsCaseInsensitiveCStringComparator())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
|
|
@ -7096,6 +7106,64 @@ nsContentUtils::IsForbiddenResponseHeader(const nsACString& aHeader)
|
||||||
aHeader.LowerCaseEqualsASCII("set-cookie2"));
|
aHeader.LowerCaseEqualsASCII("set-cookie2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
nsContentUtils::IsOverrideMethodHeader(const nsACString& headerName) {
|
||||||
|
return headerName.LowerCaseEqualsASCII("x-http-method-override") ||
|
||||||
|
headerName.LowerCaseEqualsASCII("x-http-method") ||
|
||||||
|
headerName.LowerCaseEqualsASCII("x-method-override");
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
nsContentUtils::ContainsForbiddenMethod(const nsACString& headerValue) {
|
||||||
|
bool hasInsecureMethod = false;
|
||||||
|
nsCCharSeparatedTokenizer tokenizer(headerValue, ',');
|
||||||
|
|
||||||
|
while (tokenizer.hasMoreTokens()) {
|
||||||
|
const nsDependentCSubstring& value = tokenizer.nextToken();
|
||||||
|
|
||||||
|
if (value.LowerCaseEqualsASCII("connect") ||
|
||||||
|
value.LowerCaseEqualsASCII("trace") ||
|
||||||
|
value.LowerCaseEqualsASCII("track")) {
|
||||||
|
hasInsecureMethod = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasInsecureMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool nsContentUtils::IsCorsUnsafeRequestHeaderValue(
|
||||||
|
const nsACString& aHeaderValue) {
|
||||||
|
const char* cur = aHeaderValue.BeginReading();
|
||||||
|
const char* end = aHeaderValue.EndReading();
|
||||||
|
|
||||||
|
while (cur != end) {
|
||||||
|
// Implementation of
|
||||||
|
// https://fetch.spec.whatwg.org/#cors-unsafe-request-header-byte Is less
|
||||||
|
// than a space but not a horizontal tab
|
||||||
|
if ((*cur < ' ' && *cur != '\t') || *cur == '"' || *cur == '(' ||
|
||||||
|
*cur == ')' || *cur == ':' || *cur == '<' || *cur == '>' ||
|
||||||
|
*cur == '?' || *cur == '@' || *cur == '[' || *cur == '\\' ||
|
||||||
|
*cur == ']' || *cur == '{' || *cur == '}' ||
|
||||||
|
*cur == 0x7F) { // 0x75 is DEL
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool nsContentUtils::IsAllowedNonCorsAccept(const nsACString& aHeaderValue) {
|
||||||
|
if (IsCorsUnsafeRequestHeaderValue(aHeaderValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
|
nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
|
||||||
|
|
@ -7103,6 +7171,10 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
|
||||||
nsAutoCString contentType;
|
nsAutoCString contentType;
|
||||||
nsAutoCString unused;
|
nsAutoCString unused;
|
||||||
|
|
||||||
|
if (IsCorsUnsafeRequestHeaderValue(aHeaderValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = NS_ParseRequestContentType(aHeaderValue, contentType, unused);
|
nsresult rv = NS_ParseRequestContentType(aHeaderValue, contentType, unused);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -7113,6 +7185,41 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
|
||||||
contentType.LowerCaseEqualsLiteral("multipart/form-data");
|
contentType.LowerCaseEqualsLiteral("multipart/form-data");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool nsContentUtils::IsAllowedNonCorsLanguage(const nsACString& aHeaderValue) {
|
||||||
|
const char* cur = aHeaderValue.BeginReading();
|
||||||
|
const char* end = aHeaderValue.EndReading();
|
||||||
|
|
||||||
|
while (cur != end) {
|
||||||
|
if ((*cur >= '0' && *cur <= '9') || (*cur >= 'A' && *cur <= 'Z') ||
|
||||||
|
(*cur >= 'a' && *cur <= 'z') || *cur == ' ' || *cur == '*' ||
|
||||||
|
*cur == ',' || *cur == '-' || *cur == '.' || *cur == ';' ||
|
||||||
|
*cur == '=') {
|
||||||
|
cur++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool nsContentUtils::IsCORSSafelistedRequestHeader(const nsACString& aName,
|
||||||
|
const nsACString& aValue) {
|
||||||
|
// See https://fetch.spec.whatwg.org/#cors-safelisted-request-header
|
||||||
|
if (aValue.Length() > 128) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (aName.LowerCaseEqualsLiteral("accept") &&
|
||||||
|
nsContentUtils::IsAllowedNonCorsAccept(aValue)) ||
|
||||||
|
(aName.LowerCaseEqualsLiteral("accept-language") &&
|
||||||
|
nsContentUtils::IsAllowedNonCorsLanguage(aValue)) ||
|
||||||
|
(aName.LowerCaseEqualsLiteral("content-language") &&
|
||||||
|
nsContentUtils::IsAllowedNonCorsLanguage(aValue)) ||
|
||||||
|
(aName.LowerCaseEqualsLiteral("content-type") &&
|
||||||
|
nsContentUtils::IsAllowedNonCorsContentType(aValue));
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
nsContentUtils::DOMWindowDumpEnabled()
|
nsContentUtils::DOMWindowDumpEnabled()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2425,7 +2425,8 @@ public:
|
||||||
* Returns whether a given header is forbidden for an XHR or fetch
|
* Returns whether a given header is forbidden for an XHR or fetch
|
||||||
* request.
|
* request.
|
||||||
*/
|
*/
|
||||||
static bool IsForbiddenRequestHeader(const nsACString& aHeader);
|
static bool IsForbiddenRequestHeader(const nsACString& aHeader,
|
||||||
|
const nsACString& aValue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a given header is forbidden for a system XHR
|
* Returns whether a given header is forbidden for a system XHR
|
||||||
|
|
@ -2433,18 +2434,50 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool IsForbiddenSystemRequestHeader(const nsACString& aHeader);
|
static bool IsForbiddenSystemRequestHeader(const nsACString& aHeader);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a given header has characters that aren't permitted
|
||||||
|
*/
|
||||||
|
static bool IsCorsUnsafeRequestHeaderValue(const nsACString& aHeaderValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a given Accept header value is allowed
|
||||||
|
* for a non-CORS XHR or fetch request.
|
||||||
|
*/
|
||||||
|
static bool IsAllowedNonCorsAccept(const nsACString& aHeaderValue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a given Content-Type header value is allowed
|
* Returns whether a given Content-Type header value is allowed
|
||||||
* for a non-CORS XHR or fetch request.
|
* for a non-CORS XHR or fetch request.
|
||||||
*/
|
*/
|
||||||
static bool IsAllowedNonCorsContentType(const nsACString& aHeaderValue);
|
static bool IsAllowedNonCorsContentType(const nsACString& aHeaderValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a given Content-Language or accept-language header value is
|
||||||
|
* allowed for a non-CORS XHR or fetch request.
|
||||||
|
*/
|
||||||
|
static bool IsAllowedNonCorsLanguage(const nsACString& aHeaderValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a given header and value is a CORS-safelisted request
|
||||||
|
* header per https://fetch.spec.whatwg.org/#cors-safelisted-request-header
|
||||||
|
*/
|
||||||
|
static bool IsCORSSafelistedRequestHeader(const nsACString& aName,
|
||||||
|
const nsACString& aValue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a given header is forbidden for an XHR or fetch
|
* Returns whether a given header is forbidden for an XHR or fetch
|
||||||
* response.
|
* response.
|
||||||
*/
|
*/
|
||||||
static bool IsForbiddenResponseHeader(const nsACString& aHeader);
|
static bool IsForbiddenResponseHeader(const nsACString& aHeader);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the header overrides any http methods
|
||||||
|
*/
|
||||||
|
static bool IsOverrideMethodHeader(const nsACString& headerName);
|
||||||
|
/**
|
||||||
|
* Checks whether the header value contains any forbidden method
|
||||||
|
*/
|
||||||
|
static bool ContainsForbiddenMethod(const nsACString& headerValue);
|
||||||
/**
|
/**
|
||||||
* Returns the inner window ID for the window associated with a request,
|
* Returns the inner window ID for the window associated with a request,
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "mozilla/dom/InternalHeaders.h"
|
#include "mozilla/dom/InternalHeaders.h"
|
||||||
|
|
||||||
|
#include "FetchUtil.h"
|
||||||
#include "mozilla/dom/FetchTypes.h"
|
#include "mozilla/dom/FetchTypes.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
|
|
||||||
|
|
@ -46,20 +47,112 @@ InternalHeaders::ToIPC(nsTArray<HeadersEntry>& aIPCHeaders,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
InternalHeaders::IsValidHeaderValue(const nsCString& aLowerName,
|
||||||
|
const nsCString& aNormalizedValue,
|
||||||
|
ErrorResult& aRv) {
|
||||||
|
// Steps 2 to 6 for ::Set() and ::Append() in the spec.
|
||||||
|
|
||||||
|
// Step 2
|
||||||
|
if (IsInvalidName(aLowerName, aRv) || IsInvalidValue(aNormalizedValue, aRv)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3
|
||||||
|
if (IsImmutable(aRv)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4
|
||||||
|
if (mGuard == HeadersGuardEnum::Request) {
|
||||||
|
if (IsForbiddenRequestHeader(aLowerName, aNormalizedValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5
|
||||||
|
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||||
|
nsAutoCString tempValue;
|
||||||
|
Get(aLowerName, tempValue, aRv);
|
||||||
|
|
||||||
|
if (tempValue.IsVoid()) {
|
||||||
|
tempValue = aNormalizedValue;
|
||||||
|
} else {
|
||||||
|
tempValue.Append(", ");
|
||||||
|
tempValue.Append(aNormalizedValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nsContentUtils::IsCORSSafelistedRequestHeader(aLowerName, tempValue)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 6
|
||||||
|
else if (IsForbiddenResponseHeader(aLowerName)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
InternalHeaders::Append(const nsACString& aName, const nsACString& aValue,
|
InternalHeaders::Append(const nsACString& aName, const nsACString& aValue,
|
||||||
ErrorResult& aRv)
|
ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
|
// Step 1
|
||||||
|
nsAutoCString trimValue;
|
||||||
|
NS_TrimHTTPWhitespace(aValue, trimValue);
|
||||||
|
|
||||||
|
// Steps 2 to 6
|
||||||
nsAutoCString lowerName;
|
nsAutoCString lowerName;
|
||||||
ToLowerCase(aName, lowerName);
|
ToLowerCase(aName, lowerName);
|
||||||
|
if (!IsValidHeaderValue(lowerName, trimValue, aRv)) {
|
||||||
if (IsInvalidMutableHeader(lowerName, aValue, aRv)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 7
|
||||||
SetListDirty();
|
SetListDirty();
|
||||||
|
|
||||||
mList.AppendElement(Entry(lowerName, aValue));
|
mList.AppendElement(Entry(lowerName, aValue));
|
||||||
|
|
||||||
|
// Step 8
|
||||||
|
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||||
|
RemovePrivilegedNoCorsRequestHeaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void InternalHeaders::RemovePrivilegedNoCorsRequestHeaders() {
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
|
// remove in reverse order to minimize copying
|
||||||
|
for (int32_t i = mList.Length() - 1; i >= 0; --i) {
|
||||||
|
if (IsPrivilegedNoCorsRequestHeaderName(mList[i].mName)) {
|
||||||
|
mList.RemoveElementAt(i);
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirty) {
|
||||||
|
SetListDirty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InternalHeaders::DeleteInternal(const nsCString& aLowerName,
|
||||||
|
ErrorResult& aRv) {
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
|
// remove in reverse order to minimize copying
|
||||||
|
for (int32_t i = mList.Length() - 1; i >= 0; --i) {
|
||||||
|
if (mList[i].mName.EqualsIgnoreCase(aLowerName.get())) {
|
||||||
|
mList.RemoveElementAt(i);
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dirty) {
|
||||||
|
SetListDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -68,17 +161,43 @@ InternalHeaders::Delete(const nsACString& aName, ErrorResult& aRv)
|
||||||
nsAutoCString lowerName;
|
nsAutoCString lowerName;
|
||||||
ToLowerCase(aName, lowerName);
|
ToLowerCase(aName, lowerName);
|
||||||
|
|
||||||
if (IsInvalidMutableHeader(lowerName, aRv)) {
|
// Step 1
|
||||||
|
if (IsInvalidName(lowerName, aRv)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetListDirty();
|
// Step 2
|
||||||
|
if (IsImmutable(aRv)) {
|
||||||
// remove in reverse order to minimize copying
|
return;
|
||||||
for (int32_t i = mList.Length() - 1; i >= 0; --i) {
|
|
||||||
if (lowerName == mList[i].mName) {
|
|
||||||
mList.RemoveElementAt(i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 3
|
||||||
|
nsAutoCString value;
|
||||||
|
GetInternal(lowerName, value, aRv);
|
||||||
|
if (IsForbiddenRequestHeader(lowerName, value)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4
|
||||||
|
if (mGuard == HeadersGuardEnum::Request_no_cors &&
|
||||||
|
!IsNoCorsSafelistedRequestHeaderName(lowerName) &&
|
||||||
|
!IsPrivilegedNoCorsRequestHeaderName(lowerName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5
|
||||||
|
if (IsForbiddenResponseHeader(lowerName)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Steps 6 and 7
|
||||||
|
if (!DeleteInternal(lowerName, aRv)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 8
|
||||||
|
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||||
|
RemovePrivilegedNoCorsRequestHeaders();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,12 +210,18 @@ InternalHeaders::Get(const nsACString& aName, nsACString& aValue, ErrorResult& a
|
||||||
if (IsInvalidName(lowerName, aRv)) {
|
if (IsInvalidName(lowerName, aRv)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
GetInternal(lowerName, aValue, aRv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InternalHeaders::GetInternal(const nsCString& aLowerName,
|
||||||
|
nsACString& aValue,
|
||||||
|
ErrorResult& aRv) const {
|
||||||
const char* delimiter = ",";
|
const char* delimiter = ",";
|
||||||
bool firstValueFound = false;
|
bool firstValueFound = false;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < mList.Length(); ++i) {
|
for (uint32_t i = 0; i < mList.Length(); ++i) {
|
||||||
if (lowerName == mList[i].mName) {
|
if (aLowerName == mList[i].mName) {
|
||||||
if (firstValueFound) {
|
if (firstValueFound) {
|
||||||
aValue += delimiter;
|
aValue += delimiter;
|
||||||
}
|
}
|
||||||
|
|
@ -153,13 +278,18 @@ InternalHeaders::Has(const nsACString& aName, ErrorResult& aRv) const
|
||||||
void
|
void
|
||||||
InternalHeaders::Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv)
|
InternalHeaders::Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv)
|
||||||
{
|
{
|
||||||
|
// Step 1
|
||||||
|
nsAutoCString trimValue;
|
||||||
|
NS_TrimHTTPWhitespace(aValue, trimValue);
|
||||||
|
|
||||||
|
// Steps 2 to 6
|
||||||
nsAutoCString lowerName;
|
nsAutoCString lowerName;
|
||||||
ToLowerCase(aName, lowerName);
|
ToLowerCase(aName, lowerName);
|
||||||
|
if (!IsValidHeaderValue(lowerName, trimValue, aRv)) {
|
||||||
if (IsInvalidMutableHeader(lowerName, aValue, aRv)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 7
|
||||||
SetListDirty();
|
SetListDirty();
|
||||||
|
|
||||||
int32_t firstIndex = INT32_MAX;
|
int32_t firstIndex = INT32_MAX;
|
||||||
|
|
@ -179,6 +309,11 @@ InternalHeaders::Set(const nsACString& aName, const nsACString& aValue, ErrorRes
|
||||||
} else {
|
} else {
|
||||||
mList.AppendElement(Entry(lowerName, aValue));
|
mList.AppendElement(Entry(lowerName, aValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Step 8
|
||||||
|
if (mGuard == HeadersGuardEnum::Request_no_cors) {
|
||||||
|
RemovePrivilegedNoCorsRequestHeaders();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -200,6 +335,22 @@ InternalHeaders::~InternalHeaders()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
InternalHeaders::IsNoCorsSafelistedRequestHeaderName(const nsCString& aName) {
|
||||||
|
return aName.EqualsIgnoreCase("accept") ||
|
||||||
|
aName.EqualsIgnoreCase("accept-language") ||
|
||||||
|
aName.EqualsIgnoreCase("content-language") ||
|
||||||
|
aName.EqualsIgnoreCase("content-type");
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
bool
|
||||||
|
InternalHeaders::IsPrivilegedNoCorsRequestHeaderName(
|
||||||
|
const nsCString& aName) {
|
||||||
|
return aName.EqualsIgnoreCase("range");
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
InternalHeaders::IsSimpleHeader(const nsACString& aName, const nsACString& aValue)
|
InternalHeaders::IsSimpleHeader(const nsACString& aName, const nsACString& aValue)
|
||||||
|
|
@ -207,9 +358,12 @@ InternalHeaders::IsSimpleHeader(const nsACString& aName, const nsACString& aValu
|
||||||
// Note, we must allow a null content-type value here to support
|
// Note, we must allow a null content-type value here to support
|
||||||
// get("content-type"), but the IsInvalidValue() check will prevent null
|
// get("content-type"), but the IsInvalidValue() check will prevent null
|
||||||
// from being set or appended.
|
// from being set or appended.
|
||||||
return aName.EqualsLiteral("accept") ||
|
return (aName.EqualsLiteral("accept") &&
|
||||||
aName.EqualsLiteral("accept-language") ||
|
nsContentUtils::IsAllowedNonCorsAccept(aValue)) ||
|
||||||
aName.EqualsLiteral("content-language") ||
|
(aName.EqualsLiteral("accept-language") &&
|
||||||
|
nsContentUtils::IsAllowedNonCorsLanguage(aValue))||
|
||||||
|
(aName.EqualsLiteral("content-language") &&
|
||||||
|
nsContentUtils::IsAllowedNonCorsLanguage(aValue))||
|
||||||
(aName.EqualsLiteral("content-type") &&
|
(aName.EqualsLiteral("content-type") &&
|
||||||
nsContentUtils::IsAllowedNonCorsContentType(aValue));
|
nsContentUtils::IsAllowedNonCorsContentType(aValue));
|
||||||
}
|
}
|
||||||
|
|
@ -261,10 +415,11 @@ InternalHeaders::IsImmutable(ErrorResult& aRv) const
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InternalHeaders::IsForbiddenRequestHeader(const nsACString& aName) const
|
InternalHeaders::IsForbiddenRequestHeader(const nsACString& aName,
|
||||||
|
const nsACString& aValue) const
|
||||||
{
|
{
|
||||||
return mGuard == HeadersGuardEnum::Request &&
|
return mGuard == HeadersGuardEnum::Request &&
|
||||||
nsContentUtils::IsForbiddenRequestHeader(aName);
|
nsContentUtils::IsForbiddenRequestHeader(aName, aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
@ -370,7 +525,7 @@ InternalHeaders::CORSHeaders(InternalHeaders* aHeaders, RequestCredentials aCred
|
||||||
ErrorResult result;
|
ErrorResult result;
|
||||||
|
|
||||||
nsAutoCString acExposedNames;
|
nsAutoCString acExposedNames;
|
||||||
aHeaders->GetFirst(NS_LITERAL_CSTRING("Access-Control-Expose-Headers"), acExposedNames, result);
|
aHeaders->Get(NS_LITERAL_CSTRING("Access-Control-Expose-Headers"), acExposedNames, result);
|
||||||
MOZ_ASSERT(!result.Failed());
|
MOZ_ASSERT(!result.Failed());
|
||||||
|
|
||||||
bool allowAllHeaders = false;
|
bool allowAllHeaders = false;
|
||||||
|
|
|
||||||
|
|
@ -136,8 +136,11 @@ private:
|
||||||
|
|
||||||
static bool IsInvalidName(const nsACString& aName, ErrorResult& aRv);
|
static bool IsInvalidName(const nsACString& aName, ErrorResult& aRv);
|
||||||
static bool IsInvalidValue(const nsACString& aValue, ErrorResult& aRv);
|
static bool IsInvalidValue(const nsACString& aValue, ErrorResult& aRv);
|
||||||
|
bool IsValidHeaderValue(const nsCString& aLowerName,
|
||||||
|
const nsCString& aNormalizedValue, ErrorResult& aRv);
|
||||||
bool IsImmutable(ErrorResult& aRv) const;
|
bool IsImmutable(ErrorResult& aRv) const;
|
||||||
bool IsForbiddenRequestHeader(const nsACString& aName) const;
|
bool IsForbiddenRequestHeader(const nsACString& aName,
|
||||||
|
const nsACString& aValue) const;
|
||||||
bool IsForbiddenRequestNoCorsHeader(const nsACString& aName) const;
|
bool IsForbiddenRequestNoCorsHeader(const nsACString& aName) const;
|
||||||
bool IsForbiddenRequestNoCorsHeader(const nsACString& aName,
|
bool IsForbiddenRequestNoCorsHeader(const nsACString& aName,
|
||||||
const nsACString& aValue) const;
|
const nsACString& aValue) const;
|
||||||
|
|
@ -156,11 +159,22 @@ private:
|
||||||
return IsInvalidName(aName, aRv) ||
|
return IsInvalidName(aName, aRv) ||
|
||||||
IsInvalidValue(aValue, aRv) ||
|
IsInvalidValue(aValue, aRv) ||
|
||||||
IsImmutable(aRv) ||
|
IsImmutable(aRv) ||
|
||||||
IsForbiddenRequestHeader(aName) ||
|
IsForbiddenRequestHeader(aName, aValue) ||
|
||||||
IsForbiddenRequestNoCorsHeader(aName, aValue) ||
|
IsForbiddenRequestNoCorsHeader(aName, aValue) ||
|
||||||
IsForbiddenResponseHeader(aName);
|
IsForbiddenResponseHeader(aName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemovePrivilegedNoCorsRequestHeaders();
|
||||||
|
|
||||||
|
void GetInternal(const nsCString& aLowerName, nsACString& aValue,
|
||||||
|
ErrorResult& aRv) const;
|
||||||
|
|
||||||
|
bool DeleteInternal(const nsCString& aLowerName, ErrorResult& aRv);
|
||||||
|
|
||||||
|
static bool IsNoCorsSafelistedRequestHeaderName(const nsCString& aName);
|
||||||
|
|
||||||
|
static bool IsPrivilegedNoCorsRequestHeaderName(const nsCString& aName);
|
||||||
|
|
||||||
static bool IsSimpleHeader(const nsACString& aName,
|
static bool IsSimpleHeader(const nsACString& aName,
|
||||||
const nsACString& aValue);
|
const nsACString& aValue);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1480,6 +1480,16 @@ nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
|
||||||
|
|
||||||
nsresult nsPluginInstanceOwner::ProcessKeyPress(nsIDOMEvent* aKeyEvent)
|
nsresult nsPluginInstanceOwner::ProcessKeyPress(nsIDOMEvent* aKeyEvent)
|
||||||
{
|
{
|
||||||
|
// ProcessKeyPress() may be called twice with same eKeyPress event because we
|
||||||
|
// listen in both the default and system event groups (to capture keypresses
|
||||||
|
// potentially captured by plugins that are not printable keys).
|
||||||
|
// When this is called in the latter case and the event must be fired in the
|
||||||
|
// default event group too, we don't need to do anything else and can return.
|
||||||
|
if (!aKeyEvent->WidgetEventPtr()->mFlags.mOnlySystemGroupDispatchInContent &&
|
||||||
|
aKeyEvent->WidgetEventPtr()->mFlags.mInSystemGroup) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef XP_MACOSX
|
#ifdef XP_MACOSX
|
||||||
return DispatchKeyToPlugin(aKeyEvent);
|
return DispatchKeyToPlugin(aKeyEvent);
|
||||||
#else
|
#else
|
||||||
|
|
@ -2547,6 +2557,7 @@ nsPluginInstanceOwner::Destroy()
|
||||||
content->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, false);
|
content->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, false);
|
||||||
content->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, false);
|
content->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, false);
|
||||||
content->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true);
|
content->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true);
|
||||||
|
content->RemoveSystemEventListener(NS_LITERAL_STRING("keypress"), this, true);
|
||||||
content->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true);
|
content->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true);
|
||||||
content->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
|
content->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
|
||||||
content->RemoveEventListener(NS_LITERAL_STRING("drop"), this, true);
|
content->RemoveEventListener(NS_LITERAL_STRING("drop"), this, true);
|
||||||
|
|
@ -2856,25 +2867,22 @@ nsresult nsPluginInstanceOwner::Init(nsIContent* aContent)
|
||||||
// register context menu listener
|
// register context menu listener
|
||||||
mCXMenuListener = new nsPluginDOMContextMenuListener(aContent);
|
mCXMenuListener = new nsPluginDOMContextMenuListener(aContent);
|
||||||
|
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("focus"), this, false,
|
aContent->AddEventListener(NS_LITERAL_STRING("focus"), this, false, false);
|
||||||
false);
|
aContent->AddEventListener(NS_LITERAL_STRING("blur"), this, false, false);
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("blur"), this, false,
|
aContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, false, false);
|
||||||
false);
|
aContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, false, false);
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, false,
|
aContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, false, false);
|
||||||
false);
|
aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false, false);
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, false,
|
aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false, false);
|
||||||
false);
|
aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false, false);
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, false,
|
aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false, false);
|
||||||
false);
|
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false,
|
// The "keypress" event should be handled when it's in the default event group
|
||||||
false);
|
// if the event is fired in content.
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false,
|
// Otherwise, it should be handled when it's in the system event group.
|
||||||
false);
|
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false,
|
|
||||||
false);
|
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false,
|
|
||||||
false);
|
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("keypress"), this, true);
|
aContent->AddEventListener(NS_LITERAL_STRING("keypress"), this, true);
|
||||||
|
aContent->AddSystemEventListener(NS_LITERAL_STRING("keypress"), this, true);
|
||||||
|
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("keydown"), this, true);
|
aContent->AddEventListener(NS_LITERAL_STRING("keydown"), this, true);
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("keyup"), this, true);
|
aContent->AddEventListener(NS_LITERAL_STRING("keyup"), this, true);
|
||||||
aContent->AddEventListener(NS_LITERAL_STRING("drop"), this, true);
|
aContent->AddEventListener(NS_LITERAL_STRING("drop"), this, true);
|
||||||
|
|
|
||||||
|
|
@ -3071,9 +3071,8 @@ XMLHttpRequestMainThread::SetRequestHeader(const nsACString& aName,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 3
|
// Step 3
|
||||||
nsAutoCString value(aValue);
|
nsAutoCString value;
|
||||||
static const char kHTTPWhitespace[] = "\n\t\r ";
|
NS_TrimHTTPWhitespace(aValue, value);
|
||||||
value.Trim(kHTTPWhitespace);
|
|
||||||
|
|
||||||
// Step 4
|
// Step 4
|
||||||
if (!NS_IsValidHTTPToken(aName) || !NS_IsReasonableHTTPHeaderValue(value)) {
|
if (!NS_IsValidHTTPToken(aName) || !NS_IsReasonableHTTPHeaderValue(value)) {
|
||||||
|
|
@ -3082,7 +3081,7 @@ XMLHttpRequestMainThread::SetRequestHeader(const nsACString& aName,
|
||||||
|
|
||||||
// Step 5
|
// Step 5
|
||||||
bool isPrivilegedCaller = IsSystemXHR();
|
bool isPrivilegedCaller = IsSystemXHR();
|
||||||
bool isForbiddenHeader = nsContentUtils::IsForbiddenRequestHeader(aName);
|
bool isForbiddenHeader = nsContentUtils::IsForbiddenRequestHeader(aName, aValue);
|
||||||
if (!isPrivilegedCaller && isForbiddenHeader) {
|
if (!isPrivilegedCaller && isForbiddenHeader) {
|
||||||
NS_ConvertUTF8toUTF16 name(aName);
|
NS_ConvertUTF8toUTF16 name(aName);
|
||||||
const char16_t* params[] = { name.get() };
|
const char16_t* params[] = { name.get() };
|
||||||
|
|
|
||||||
|
|
@ -5235,6 +5235,9 @@ pref("dom.storageManager.enabled", false);
|
||||||
// See application preferences for appropriate defaults.
|
// See application preferences for appropriate defaults.
|
||||||
pref("prompts.authentication_dialog_abuse_limit", 0);
|
pref("prompts.authentication_dialog_abuse_limit", 0);
|
||||||
|
|
||||||
|
// Whether content handling dialog is window modal
|
||||||
|
pref("prompts.content_handling_dialog_modal.enabled", false);
|
||||||
|
|
||||||
// Whether module scripts (<script type="module">) are enabled for content.
|
// Whether module scripts (<script type="module">) are enabled for content.
|
||||||
pref("dom.moduleScripts.enabled", true);
|
pref("dom.moduleScripts.enabled", true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -520,6 +520,12 @@ bool NS_IsValidHTTPToken(const nsACString &aToken)
|
||||||
return mozilla::net::nsHttp::IsValidToken(aToken);
|
return mozilla::net::nsHttp::IsValidToken(aToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NS_TrimHTTPWhitespace(const nsACString& aSource, nsACString& aDest)
|
||||||
|
{
|
||||||
|
mozilla::net::nsHttp::TrimHTTPWhitespace(aSource, aDest);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
NS_NewLoadGroup(nsILoadGroup **aResult, nsIPrincipal *aPrincipal)
|
NS_NewLoadGroup(nsILoadGroup **aResult, nsIPrincipal *aPrincipal)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -959,6 +959,11 @@ bool NS_IsReasonableHTTPHeaderValue(const nsACString &aValue);
|
||||||
*/
|
*/
|
||||||
bool NS_IsValidHTTPToken(const nsACString &aToken);
|
bool NS_IsValidHTTPToken(const nsACString &aToken);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strip the leading or trailing HTTP whitespace per fetch spec section 2.2.
|
||||||
|
*/
|
||||||
|
void NS_TrimHTTPWhitespace(const nsACString& aSource, nsACString& aDest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if the given request must be upgraded to HTTPS.
|
* Return true if the given request must be upgraded to HTTPS.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,18 @@ nsHttp::GetProtocolVersion(uint32_t pv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void
|
||||||
|
nsHttp::TrimHTTPWhitespace(const nsACString& aSource, nsACString& aDest)
|
||||||
|
{
|
||||||
|
nsAutoCString str(aSource);
|
||||||
|
|
||||||
|
// HTTP whitespace 0x09: '\t', 0x0A: '\n', 0x0D: '\r', 0x20: ' '
|
||||||
|
static const char kHTTPWhitespace[] = "\t\n\r ";
|
||||||
|
str.Trim(kHTTPWhitespace);
|
||||||
|
aDest.Assign(str);
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool
|
bool
|
||||||
nsHttp::IsReasonableHeaderValue(const nsACString &s)
|
nsHttp::IsReasonableHeaderValue(const nsACString &s)
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,10 @@ struct nsHttp
|
||||||
return IsValidToken(s.BeginReading(), s.EndReading());
|
return IsValidToken(s.BeginReading(), s.EndReading());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strip the leading or trailing HTTP whitespace per fetch spec section 2.2.
|
||||||
|
static void TrimHTTPWhitespace(const nsACString& aSource,
|
||||||
|
nsACString& aDest);
|
||||||
|
|
||||||
// Returns true if the specified value is reasonable given the defintion
|
// Returns true if the specified value is reasonable given the defintion
|
||||||
// in RFC 2616 section 4.2. Full strict validation is not performed
|
// in RFC 2616 section 4.2. Full strict validation is not performed
|
||||||
// currently as it would require full parsing of the value.
|
// currently as it would require full parsing of the value.
|
||||||
|
|
|
||||||
|
|
@ -2313,6 +2313,16 @@ WebSocketChannel::CleanupConnection()
|
||||||
{
|
{
|
||||||
LOG(("WebSocketChannel::CleanupConnection() %p", this));
|
LOG(("WebSocketChannel::CleanupConnection() %p", this));
|
||||||
|
|
||||||
|
// This should run on the Socket Thread to prevent potential races.
|
||||||
|
bool onSocketThread;
|
||||||
|
nsresult rv = mSocketThread->IsOnCurrentThread(&onSocketThread);
|
||||||
|
if (NS_SUCCEEDED(rv) && !onSocketThread) {
|
||||||
|
mSocketThread->Dispatch(
|
||||||
|
NewRunnableMethod(this, &WebSocketChannel::CleanupConnection),
|
||||||
|
NS_DISPATCH_NORMAL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (mLingeringCloseTimer) {
|
if (mLingeringCloseTimer) {
|
||||||
mLingeringCloseTimer->Cancel();
|
mLingeringCloseTimer->Cancel();
|
||||||
mLingeringCloseTimer = nullptr;
|
mLingeringCloseTimer = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -181,11 +181,13 @@ static bool scanArp(char *ip, char *mac, size_t maclen)
|
||||||
if (st == 0 || errno != ENOMEM) {
|
if (st == 0 || errno != ENOMEM) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
needed += needed / 8;
|
size_t increased = needed;
|
||||||
|
increased += increased / 8;
|
||||||
|
|
||||||
auto tmp = MakeUnique<char[]>(needed);
|
auto tmp = MakeUnique<char[]>(increased);
|
||||||
memcpy(&tmp[0], &buf[0], needed);
|
memcpy(&tmp[0], &buf[0], needed);
|
||||||
buf = Move(tmp);
|
buf = Move(tmp);
|
||||||
|
needed = increased;
|
||||||
}
|
}
|
||||||
if (st == -1) {
|
if (st == -1) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,8 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
|
|
||||||
const Cc = Components.classes;
|
const {utils: Cu, interfaces: Ci, classes: Cc, results: Cr} = Components;
|
||||||
const Ci = Components.interfaces;
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
const Cr = Components.results;
|
|
||||||
|
|
||||||
const CONTENT_HANDLING_URL = "chrome://mozapps/content/handling/dialog.xul";
|
const CONTENT_HANDLING_URL = "chrome://mozapps/content/handling/dialog.xul";
|
||||||
const STRINGBUNDLE_URL = "chrome://mozapps/locale/handling/handling.properties";
|
const STRINGBUNDLE_URL = "chrome://mozapps/locale/handling/handling.properties";
|
||||||
|
|
@ -64,13 +63,16 @@ nsContentDispatchChooser.prototype =
|
||||||
params.appendElement(aURI, false);
|
params.appendElement(aURI, false);
|
||||||
params.appendElement(aWindowContext, false);
|
params.appendElement(aWindowContext, false);
|
||||||
|
|
||||||
|
var features = "chrome,dialog=yes,resizable,centerscreen";
|
||||||
|
if (Services.prefs.getBoolPref("prompts.content_handling_dialog_modal.enabled")) {
|
||||||
|
features += ",modal";
|
||||||
|
} else {
|
||||||
|
features += ",dependent";
|
||||||
|
}
|
||||||
|
|
||||||
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
|
||||||
getService(Ci.nsIWindowWatcher);
|
getService(Ci.nsIWindowWatcher);
|
||||||
ww.openWindow(window,
|
ww.openWindow(window, CONTENT_HANDLING_URL, null, features, params);
|
||||||
CONTENT_HANDLING_URL,
|
|
||||||
null,
|
|
||||||
"chrome,dialog=yes,resizable,centerscreen",
|
|
||||||
params);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// nsISupports
|
// nsISupports
|
||||||
|
|
|
||||||
|
|
@ -1715,16 +1715,18 @@ nsLocalFile::GetNativeTarget(nsACString& aResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t size = (int32_t)symStat.st_size;
|
int32_t size = (int32_t)symStat.st_size;
|
||||||
char* target = (char*)moz_xmalloc(size + 1);
|
nsAutoCString target;
|
||||||
if (!target) {
|
if (!target.SetLength(size, mozilla::fallible)) {
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readlink(mPath.get(), target, (size_t)size) < 0) {
|
ssize_t written = readlink(mPath.get(), target.BeginWriting(), size_t(size));
|
||||||
free(target);
|
if (written < 0) {
|
||||||
return NSRESULT_FOR_ERRNO();
|
return NSRESULT_FOR_ERRNO();
|
||||||
}
|
}
|
||||||
target[size] = '\0';
|
// Target might have changed since the lstat call, or lstat might lie, see bug
|
||||||
|
// 1791029.
|
||||||
|
target.Truncate(written);
|
||||||
|
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
nsCOMPtr<nsIFile> self(this);
|
nsCOMPtr<nsIFile> self(this);
|
||||||
|
|
@ -1740,7 +1742,7 @@ nsLocalFile::GetNativeTarget(nsACString& aResult)
|
||||||
if (NS_FAILED(rv = self->GetParent(getter_AddRefs(parent)))) {
|
if (NS_FAILED(rv = self->GetParent(getter_AddRefs(parent)))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (NS_FAILED(rv = parent->AppendRelativeNativePath(nsDependentCString(target)))) {
|
if (NS_FAILED(rv = parent->AppendRelativeNativePath(target))) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (NS_FAILED(rv = parent->GetNativePath(aResult))) {
|
if (NS_FAILED(rv = parent->GetNativePath(aResult))) {
|
||||||
|
|
@ -1765,26 +1767,24 @@ nsLocalFile::GetNativeTarget(nsACString& aResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t newSize = (int32_t)symStat.st_size;
|
int32_t newSize = (int32_t)symStat.st_size;
|
||||||
if (newSize > size) {
|
size = newSize;
|
||||||
char* newTarget = (char*)moz_xrealloc(target, newSize + 1);
|
nsAutoCString newTarget;
|
||||||
if (!newTarget) {
|
if (!newTarget.SetLength(size, mozilla::fallible)) {
|
||||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
target = newTarget;
|
|
||||||
size = newSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t linkLen = readlink(flatRetval.get(), target, size);
|
ssize_t linkLen = readlink(flatRetval.get(), newTarget.BeginWriting(), size);
|
||||||
if (linkLen == -1) {
|
if (linkLen == -1) {
|
||||||
rv = NSRESULT_FOR_ERRNO();
|
rv = NSRESULT_FOR_ERRNO();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
target[linkLen] = '\0';
|
// Target might have changed since the lstat call, or lstat might lie, see bug
|
||||||
|
// 1791029.
|
||||||
|
newTarget.Truncate(linkLen);
|
||||||
|
target = newTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(target);
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
aResult.Truncate();
|
aResult.Truncate();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue