Open Bug 1186007 Opened 5 years ago Updated 10 months ago

Prevent calling DisconnectFromOwner from anywhere but nsGlobalWindow

Categories

(Core :: DOM: Core & HTML, defect)

defect
Not set

Tracking

()

People

(Reporter: ehsan, Unassigned)

References

Details

Right now this function can be called from anywhere, and doing so will result in things similar to bug 1176898.

There is a neat trick that we can employ to make this impossible to happen, see the program below for example:

class Base {
  friend class Friend;
  struct Secret {};
public:
  struct Token {
    Token(const Secret&) {}
  };
  virtual void DisconnectFromOwner(const Token& token) {};
};

struct Derived : Base {
  virtual void DisconnectFromOwner(const Token& token) {
    foo();
    Base::DisconnectFromOwner(token);
  }
  void foo() {};
};

struct Friend {
  void test() {
    Derived d;
    d.DisconnectFromOwner(Base::Token(Base::Secret()));
  }
};

struct NonFriend {
  void test() {
    Derived d;
    d.DisconnectFromOwner(Base::Token(Base::Secret()));
  }
};

Compiling this will give:

$ clang -c test.cpp
test.cpp:29:45: error: 'Secret' is a private member of 'Base'
    d.DisconnectFromOwner(Base::Token(Base::Secret()));
                                            ^
test.cpp:3:10: note: implicitly declared private here
  struct Secret {};
         ^
1 error generated.

Which is what we want.

The trick is to make DisconnectFromOwner take a const Token& argument, to make it require a Token object constructed on the stack somehow before you can call that function.  The Token type itself should be world visible so that derived versions of DisconnectFromOwner can be declared.  But the constructor of the Token type will take a reference to a Secret type which is a private member of DOMEventTargetHelper, and DETH will friend nsGlobalWindow.  This will effectively make DisconnectFromOwner uncallable from elsewhere.
IIRC this is how bent's FriendKey stuff works.
Yes, looks like that's exactly how it works!
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.