Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
roytam1 2022-11-25 11:46:08 +08:00
commit de0b4ac202
15 changed files with 437 additions and 77 deletions

View file

@ -7058,16 +7058,26 @@ nsContentUtils::HasDistributedChildren(nsIContent* aContent)
// static
bool
nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader)
nsContentUtils::IsForbiddenRequestHeader(const nsACString& aHeader,
const nsACString& aValue)
{
if (IsForbiddenSystemRequestHeader(aHeader)) {
return true;
}
if ((nsContentUtils::IsOverrideMethodHeader(aHeader) &&
nsContentUtils::ContainsForbiddenMethod(aValue))) {
return true;
}
return StringBeginsWith(aHeader, NS_LITERAL_CSTRING("proxy-"),
nsCaseInsensitiveCStringComparator()) ||
StringBeginsWith(aHeader, NS_LITERAL_CSTRING("sec-"),
nsCaseInsensitiveCStringComparator());
if (StringBeginsWith(aHeader, NS_LITERAL_CSTRING("proxy-"),
nsCaseInsensitiveCStringComparator()) ||
StringBeginsWith(aHeader, NS_LITERAL_CSTRING("sec-"),
nsCaseInsensitiveCStringComparator())) {
return true;
}
return false;
}
// static
@ -7096,6 +7106,64 @@ nsContentUtils::IsForbiddenResponseHeader(const nsACString& aHeader)
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
bool
nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
@ -7103,6 +7171,10 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
nsAutoCString contentType;
nsAutoCString unused;
if (IsCorsUnsafeRequestHeaderValue(aHeaderValue)) {
return false;
}
nsresult rv = NS_ParseRequestContentType(aHeaderValue, contentType, unused);
if (NS_FAILED(rv)) {
return false;
@ -7113,6 +7185,41 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue)
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
nsContentUtils::DOMWindowDumpEnabled()
{

View file

@ -2425,7 +2425,8 @@ public:
* Returns whether a given header is forbidden for an XHR or fetch
* 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
@ -2433,18 +2434,50 @@ public:
*/
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
* for a non-CORS XHR or fetch request.
*/
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
* response.
*/
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,
*/

View file

@ -5,6 +5,7 @@
#include "mozilla/dom/InternalHeaders.h"
#include "FetchUtil.h"
#include "mozilla/dom/FetchTypes.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
InternalHeaders::Append(const nsACString& aName, const nsACString& aValue,
ErrorResult& aRv)
{
// Step 1
nsAutoCString trimValue;
NS_TrimHTTPWhitespace(aValue, trimValue);
// Steps 2 to 6
nsAutoCString lowerName;
ToLowerCase(aName, lowerName);
if (IsInvalidMutableHeader(lowerName, aValue, aRv)) {
if (!IsValidHeaderValue(lowerName, trimValue, aRv)) {
return;
}
// Step 7
SetListDirty();
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
@ -68,17 +161,43 @@ InternalHeaders::Delete(const nsACString& aName, ErrorResult& aRv)
nsAutoCString lowerName;
ToLowerCase(aName, lowerName);
if (IsInvalidMutableHeader(lowerName, aRv)) {
// Step 1
if (IsInvalidName(lowerName, aRv)) {
return;
}
SetListDirty();
// Step 2
if (IsImmutable(aRv)) {
return;
}
// remove in reverse order to minimize copying
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)) {
return;
}
GetInternal(lowerName, aValue, aRv);
}
void
InternalHeaders::GetInternal(const nsCString& aLowerName,
nsACString& aValue,
ErrorResult& aRv) const {
const char* delimiter = ",";
bool firstValueFound = false;
for (uint32_t i = 0; i < mList.Length(); ++i) {
if (lowerName == mList[i].mName) {
if (aLowerName == mList[i].mName) {
if (firstValueFound) {
aValue += delimiter;
}
@ -153,13 +278,18 @@ InternalHeaders::Has(const nsACString& aName, ErrorResult& aRv) const
void
InternalHeaders::Set(const nsACString& aName, const nsACString& aValue, ErrorResult& aRv)
{
// Step 1
nsAutoCString trimValue;
NS_TrimHTTPWhitespace(aValue, trimValue);
// Steps 2 to 6
nsAutoCString lowerName;
ToLowerCase(aName, lowerName);
if (IsInvalidMutableHeader(lowerName, aValue, aRv)) {
if (!IsValidHeaderValue(lowerName, trimValue, aRv)) {
return;
}
// Step 7
SetListDirty();
int32_t firstIndex = INT32_MAX;
@ -179,6 +309,11 @@ InternalHeaders::Set(const nsACString& aName, const nsACString& aValue, ErrorRes
} else {
mList.AppendElement(Entry(lowerName, aValue));
}
// Step 8
if (mGuard == HeadersGuardEnum::Request_no_cors) {
RemovePrivilegedNoCorsRequestHeaders();
}
}
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
bool
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
// get("content-type"), but the IsInvalidValue() check will prevent null
// from being set or appended.
return aName.EqualsLiteral("accept") ||
aName.EqualsLiteral("accept-language") ||
aName.EqualsLiteral("content-language") ||
return (aName.EqualsLiteral("accept") &&
nsContentUtils::IsAllowedNonCorsAccept(aValue)) ||
(aName.EqualsLiteral("accept-language") &&
nsContentUtils::IsAllowedNonCorsLanguage(aValue))||
(aName.EqualsLiteral("content-language") &&
nsContentUtils::IsAllowedNonCorsLanguage(aValue))||
(aName.EqualsLiteral("content-type") &&
nsContentUtils::IsAllowedNonCorsContentType(aValue));
}
@ -261,10 +415,11 @@ InternalHeaders::IsImmutable(ErrorResult& aRv) const
}
bool
InternalHeaders::IsForbiddenRequestHeader(const nsACString& aName) const
InternalHeaders::IsForbiddenRequestHeader(const nsACString& aName,
const nsACString& aValue) const
{
return mGuard == HeadersGuardEnum::Request &&
nsContentUtils::IsForbiddenRequestHeader(aName);
nsContentUtils::IsForbiddenRequestHeader(aName, aValue);
}
bool
@ -370,7 +525,7 @@ InternalHeaders::CORSHeaders(InternalHeaders* aHeaders, RequestCredentials aCred
ErrorResult result;
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());
bool allowAllHeaders = false;

View file

@ -136,8 +136,11 @@ private:
static bool IsInvalidName(const nsACString& aName, 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 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 nsACString& aValue) const;
@ -156,11 +159,22 @@ private:
return IsInvalidName(aName, aRv) ||
IsInvalidValue(aValue, aRv) ||
IsImmutable(aRv) ||
IsForbiddenRequestHeader(aName) ||
IsForbiddenRequestHeader(aName, aValue) ||
IsForbiddenRequestNoCorsHeader(aName, aValue) ||
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,
const nsACString& aValue);

View file

@ -1480,6 +1480,16 @@ nsresult nsPluginInstanceOwner::DispatchFocusToPlugin(nsIDOMEvent* aFocusEvent)
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
return DispatchKeyToPlugin(aKeyEvent);
#else
@ -2547,6 +2557,7 @@ nsPluginInstanceOwner::Destroy()
content->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, false);
content->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, false);
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("keyup"), this, true);
content->RemoveEventListener(NS_LITERAL_STRING("drop"), this, true);
@ -2856,25 +2867,22 @@ nsresult nsPluginInstanceOwner::Init(nsIContent* aContent)
// register context menu listener
mCXMenuListener = new nsPluginDOMContextMenuListener(aContent);
aContent->AddEventListener(NS_LITERAL_STRING("focus"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("blur"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false,
false);
aContent->AddEventListener(NS_LITERAL_STRING("focus"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("blur"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseup"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mousedown"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mousemove"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("click"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("dblclick"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseover"), this, false, false);
aContent->AddEventListener(NS_LITERAL_STRING("mouseout"), this, false, false);
// The "keypress" event should be handled when it's in the default event group
// if the event is fired in content.
// Otherwise, it should be handled when it's in the system event group.
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("keyup"), this, true);
aContent->AddEventListener(NS_LITERAL_STRING("drop"), this, true);

View file

@ -3071,9 +3071,8 @@ XMLHttpRequestMainThread::SetRequestHeader(const nsACString& aName,
}
// Step 3
nsAutoCString value(aValue);
static const char kHTTPWhitespace[] = "\n\t\r ";
value.Trim(kHTTPWhitespace);
nsAutoCString value;
NS_TrimHTTPWhitespace(aValue, value);
// Step 4
if (!NS_IsValidHTTPToken(aName) || !NS_IsReasonableHTTPHeaderValue(value)) {
@ -3082,7 +3081,7 @@ XMLHttpRequestMainThread::SetRequestHeader(const nsACString& aName,
// Step 5
bool isPrivilegedCaller = IsSystemXHR();
bool isForbiddenHeader = nsContentUtils::IsForbiddenRequestHeader(aName);
bool isForbiddenHeader = nsContentUtils::IsForbiddenRequestHeader(aName, aValue);
if (!isPrivilegedCaller && isForbiddenHeader) {
NS_ConvertUTF8toUTF16 name(aName);
const char16_t* params[] = { name.get() };

View file

@ -5235,6 +5235,9 @@ pref("dom.storageManager.enabled", false);
// See application preferences for appropriate defaults.
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.
pref("dom.moduleScripts.enabled", true);

View file

@ -520,6 +520,12 @@ bool NS_IsValidHTTPToken(const nsACString &aToken)
return mozilla::net::nsHttp::IsValidToken(aToken);
}
void
NS_TrimHTTPWhitespace(const nsACString& aSource, nsACString& aDest)
{
mozilla::net::nsHttp::TrimHTTPWhitespace(aSource, aDest);
}
nsresult
NS_NewLoadGroup(nsILoadGroup **aResult, nsIPrincipal *aPrincipal)
{

View file

@ -959,6 +959,11 @@ bool NS_IsReasonableHTTPHeaderValue(const nsACString &aValue);
*/
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.
*/

View file

@ -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
bool
nsHttp::IsReasonableHeaderValue(const nsACString &s)

View file

@ -148,6 +148,10 @@ struct nsHttp
static inline bool IsValidToken(const nsACString &s) {
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
// in RFC 2616 section 4.2. Full strict validation is not performed

View file

@ -2313,6 +2313,16 @@ WebSocketChannel::CleanupConnection()
{
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) {
mLingeringCloseTimer->Cancel();
mLingeringCloseTimer = nullptr;

View file

@ -181,11 +181,13 @@ static bool scanArp(char *ip, char *mac, size_t maclen)
if (st == 0 || errno != ENOMEM) {
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);
buf = Move(tmp);
needed = increased;
}
if (st == -1) {
return false;

View file

@ -6,9 +6,8 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
// Constants
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const {utils: Cu, interfaces: Ci, classes: Cc, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
const CONTENT_HANDLING_URL = "chrome://mozapps/content/handling/dialog.xul";
const STRINGBUNDLE_URL = "chrome://mozapps/locale/handling/handling.properties";
@ -64,13 +63,16 @@ nsContentDispatchChooser.prototype =
params.appendElement(aURI, 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"].
getService(Ci.nsIWindowWatcher);
ww.openWindow(window,
CONTENT_HANDLING_URL,
null,
"chrome,dialog=yes,resizable,centerscreen",
params);
ww.openWindow(window, CONTENT_HANDLING_URL, null, features, params);
},
// nsISupports

View file

@ -1715,16 +1715,18 @@ nsLocalFile::GetNativeTarget(nsACString& aResult)
}
int32_t size = (int32_t)symStat.st_size;
char* target = (char*)moz_xmalloc(size + 1);
if (!target) {
nsAutoCString target;
if (!target.SetLength(size, mozilla::fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
if (readlink(mPath.get(), target, (size_t)size) < 0) {
free(target);
ssize_t written = readlink(mPath.get(), target.BeginWriting(), size_t(size));
if (written < 0) {
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;
nsCOMPtr<nsIFile> self(this);
@ -1740,7 +1742,7 @@ nsLocalFile::GetNativeTarget(nsACString& aResult)
if (NS_FAILED(rv = self->GetParent(getter_AddRefs(parent)))) {
break;
}
if (NS_FAILED(rv = parent->AppendRelativeNativePath(nsDependentCString(target)))) {
if (NS_FAILED(rv = parent->AppendRelativeNativePath(target))) {
break;
}
if (NS_FAILED(rv = parent->GetNativePath(aResult))) {
@ -1765,26 +1767,24 @@ nsLocalFile::GetNativeTarget(nsACString& aResult)
}
int32_t newSize = (int32_t)symStat.st_size;
if (newSize > size) {
char* newTarget = (char*)moz_xrealloc(target, newSize + 1);
if (!newTarget) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
target = newTarget;
size = newSize;
size = newSize;
nsAutoCString newTarget;
if (!newTarget.SetLength(size, mozilla::fallible)) {
rv = NS_ERROR_OUT_OF_MEMORY;
break;
}
int32_t linkLen = readlink(flatRetval.get(), target, size);
ssize_t linkLen = readlink(flatRetval.get(), newTarget.BeginWriting(), size);
if (linkLen == -1) {
rv = NSRESULT_FOR_ERRNO();
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)) {
aResult.Truncate();
}