Verified Commit 9e8a90ef authored by Jonathan Kew's avatar Jonathan Kew Committed by ma1
Browse files

Bug 2045612 - Take ownership of the state in RestoreFormControlState. a=pascalc DONTBUILD

parent 046b2007
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -3239,12 +3239,13 @@ bool nsGenericHTMLFormControlElementWithState::RestoreFormControlState() {
    return false;
  }

  // Get the pres state for this key
  PresState* state = history->GetState(mStateKey);
  // Take ownership of the pres state for this key: RestoreState() can run
  // script (e.g. by synchronously committing an IME composition), which may
  // re-enter restoration for the same key and free a table-owned state while
  // we are still using it.
  UniquePtr<PresState> state = history->TakeState(mStateKey);
  if (state) {
    bool result = RestoreState(state);
    history->RemoveState(mStateKey);
    return result;
    return RestoreState(state.get());
  }

  return false;
+8 −0
Original line number Diff line number Diff line
@@ -80,6 +80,14 @@ interface nsILayoutHistoryState : nsISupports
   */
  [noscript, notxpcom, nostdcall] void RemoveState(in nsCString aKey);

  /**
   * Remove the state object for |aKey| from the table and transfer
   * ownership of it to the caller. Use this instead of GetState() when
   * the state is consumed by code that may run script, so that a
   * re-entrant RemoveState()/Reset() cannot free it while in use.
   */
  [noscript, notxpcom, nostdcall] PresStateUnique TakeState(in nsCString aKey);

  /**
   * Check whether this history has any states in it
   */
+15 −0
Original line number Diff line number Diff line
@@ -116,6 +116,21 @@ void nsLayoutHistoryState::RemoveState(const nsCString& aKey) {
  mStates.Remove(aKey);
}

UniquePtr<PresState> nsLayoutHistoryState::TakeState(const nsCString& aKey) {
  UniquePtr<PresState> state;
  if (auto entry = mStates.Extract(aKey)) {
    state = std::move(*entry);
  }

  if (state && mScrollPositionOnly) {
    // Ensure any state that shouldn't be restored is removed
    state->contentData() = void_t();
    state->disabledSet() = false;
  }

  return state;
}

bool nsLayoutHistoryState::HasStates() { return mStates.Count() != 0; }

void nsLayoutHistoryState::SetScrollPositionOnly(const bool aFlag) {