forked from mirrors/gecko-dev
		
	 b2bd8c603a
			
		
	
	
		b2bd8c603a
		
	
	
	
	
		
			
			I don't immediate see an reason about why this assertion can fail. Given the test (browser_ext_tabs_move_window.js) closes some windows near the end, I wonder if it's possible for RecvOnDataAvailable to be run after ActorDestroy. Differential Revision: https://phabricator.services.mozilla.com/D167270
		
			
				
	
	
		
			90 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
	
		
			2.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "mozilla/dom/JSValidatorChild.h"
 | |
| #include "mozilla/ipc/Endpoint.h"
 | |
| 
 | |
| using namespace mozilla::dom;
 | |
| 
 | |
| mozilla::ipc::IPCResult JSValidatorChild::RecvIsOpaqueResponseAllowed(
 | |
|     IsOpaqueResponseAllowedResolver&& aResolver) {
 | |
|   mResolver.emplace(aResolver);
 | |
| 
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult JSValidatorChild::RecvOnDataAvailable(Shmem&& aData) {
 | |
|   if (!mResolver) {
 | |
|     MOZ_ASSERT(!CanSend());
 | |
|     return IPC_OK();
 | |
|   }
 | |
| 
 | |
|   if (!mSourceBytes.Append(Span(aData.get<char>(), aData.Size<char>()),
 | |
|                            mozilla::fallible)) {
 | |
|     // To prevent an attacker from flood the validation process,
 | |
|     // we don't validate here.
 | |
|     Resolve(ValidatorResult::Failure);
 | |
|   }
 | |
|   DeallocShmem(aData);
 | |
| 
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| mozilla::ipc::IPCResult JSValidatorChild::RecvOnStopRequest(
 | |
|     const nsresult& aReason) {
 | |
|   if (!mResolver) {
 | |
|     return IPC_OK();
 | |
|   }
 | |
| 
 | |
|   if (NS_FAILED(aReason)) {
 | |
|     Resolve(ValidatorResult::Failure);
 | |
|   } else {
 | |
|     Resolve(ShouldAllowJS());
 | |
|   }
 | |
| 
 | |
|   return IPC_OK();
 | |
| }
 | |
| 
 | |
| void JSValidatorChild::ActorDestroy(ActorDestroyReason aReason) {
 | |
|   if (mResolver) {
 | |
|     Resolve(ValidatorResult::Failure);
 | |
|   }
 | |
| };
 | |
| 
 | |
| void JSValidatorChild::Resolve(ValidatorResult aResult) {
 | |
|   MOZ_ASSERT(mResolver);
 | |
|   Maybe<Shmem> data = Nothing();
 | |
|   if (aResult == ValidatorResult::JavaScript && !mSourceBytes.IsEmpty()) {
 | |
|     Shmem sharedData;
 | |
|     nsresult rv =
 | |
|         JSValidatorUtils::CopyCStringToShmem(this, mSourceBytes, sharedData);
 | |
|     if (NS_SUCCEEDED(rv)) {
 | |
|       data = Some(std::move(sharedData));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   mResolver.ref()(Tuple<mozilla::Maybe<Shmem>&&, const ValidatorResult&>(
 | |
|       std::move(data), aResult));
 | |
|   mResolver.reset();
 | |
| }
 | |
| 
 | |
| JSValidatorChild::ValidatorResult JSValidatorChild::ShouldAllowJS() const {
 | |
|   // mSourceBytes could be empty when
 | |
|   // 1. No OnDataAvailable calls
 | |
|   // 2. Failed to allocate shmem
 | |
| 
 | |
|   // The empty document parses as JavaScript, so for clarity we have a condition
 | |
|   // separately for that.
 | |
|   if (mSourceBytes.IsEmpty()) {
 | |
|     return ValidatorResult::JavaScript;
 | |
|   }
 | |
| 
 | |
|   if (StringBeginsWith(NS_ConvertUTF8toUTF16(mSourceBytes), u"{"_ns)) {
 | |
|     return ValidatorResult::JSON;
 | |
|   }
 | |
| 
 | |
|   return ValidatorResult::JavaScript;
 | |
| }
 |