docshell/base/SerializedLoadContext.h
author Nika Layzell <nika@thelayzells.com>
Wed, 16 Sep 2020 20:47:55 +0000
changeset 549331 ab7d302fd3186b10ada9264528c80f6840e44571
parent 469832 2846ae7210336f4e8c72076edaab027e7027ac8f
permissions -rw-r--r--
Bug 1659696 - Check PendingInitialization before targeting in window.open, r=kmag This requires adding the flag as a synced field on the BrowsingContext, and checking it in a few more places. Attempts to open a new window in this racy manner will now raise an exception. This should avoid the issue from bug 1658854 by blocking the buggy attempts to load before the nested event loop has been exited. Differential Revision: https://phabricator.services.mozilla.com/D87927

/* -*- 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/. */

#ifndef SerializedLoadContext_h
#define SerializedLoadContext_h

#include "base/basictypes.h"
#include "ipc/IPCMessageUtils.h"
#include "mozilla/BasePrincipal.h"

class nsILoadContext;

/*
 *  This file contains the IPC::SerializedLoadContext class, which is used to
 *  copy data across IPDL from Child process contexts so it is available in the
 *  Parent.
 */

class nsIChannel;
class nsIWebSocketChannel;

namespace IPC {

class SerializedLoadContext {
 public:
  SerializedLoadContext()
      : mIsNotNull(false),
        mIsPrivateBitValid(false),
        mIsContent(false),
        mUseRemoteTabs(false),
        mUseRemoteSubframes(false),
        mUseTrackingProtection(false) {
    Init(nullptr);
  }

  explicit SerializedLoadContext(nsILoadContext* aLoadContext);
  explicit SerializedLoadContext(nsIChannel* aChannel);
  explicit SerializedLoadContext(nsIWebSocketChannel* aChannel);

  void Init(nsILoadContext* aLoadContext);

  bool IsNotNull() const { return mIsNotNull; }
  bool IsPrivateBitValid() const { return mIsPrivateBitValid; }

  // used to indicate if child-side LoadContext * was null.
  bool mIsNotNull;
  // used to indicate if child-side mUsePrivateBrowsing flag is valid, even if
  // mIsNotNull is false, i.e., child LoadContext was null.
  bool mIsPrivateBitValid;
  bool mIsContent;
  bool mUseRemoteTabs;
  bool mUseRemoteSubframes;
  bool mUseTrackingProtection;
  mozilla::OriginAttributes mOriginAttributes;
};

// Function to serialize over IPDL
template <>
struct ParamTraits<SerializedLoadContext> {
  typedef SerializedLoadContext paramType;

  static void Write(Message* aMsg, const paramType& aParam) {
    nsAutoCString suffix;
    aParam.mOriginAttributes.CreateSuffix(suffix);

    WriteParam(aMsg, aParam.mIsNotNull);
    WriteParam(aMsg, aParam.mIsContent);
    WriteParam(aMsg, aParam.mIsPrivateBitValid);
    WriteParam(aMsg, aParam.mUseRemoteTabs);
    WriteParam(aMsg, aParam.mUseRemoteSubframes);
    WriteParam(aMsg, aParam.mUseTrackingProtection);
    WriteParam(aMsg, suffix);
  }

  static bool Read(const Message* aMsg, PickleIterator* aIter,
                   paramType* aResult) {
    nsAutoCString suffix;
    if (!ReadParam(aMsg, aIter, &aResult->mIsNotNull) ||
        !ReadParam(aMsg, aIter, &aResult->mIsContent) ||
        !ReadParam(aMsg, aIter, &aResult->mIsPrivateBitValid) ||
        !ReadParam(aMsg, aIter, &aResult->mUseRemoteTabs) ||
        !ReadParam(aMsg, aIter, &aResult->mUseRemoteSubframes) ||
        !ReadParam(aMsg, aIter, &aResult->mUseTrackingProtection) ||
        !ReadParam(aMsg, aIter, &suffix)) {
      return false;
    }
    return aResult->mOriginAttributes.PopulateFromSuffix(suffix);
  }
};

}  // namespace IPC

#endif  // SerializedLoadContext_h