Hi all,

In C++, if a constructor can be invoked with one argument (that is if it has 1 required and N>=0 optional arguments, or N>0 optional arguments), it provides an implicit conversion from the type of the first argument to the class's type. This can sometimes produce surprising results, for example:

template <class T>
struct SmartPtr {
  SmartPtr(T* aObj)
    : mObj(aObj)
  {}
  ~SmartPtr() {
    delete mObj;
  }
private:
  T* mObj;
};

struct Foo {
  virtual void DoSomething();
};

void f(const SmartPtr<Foo>& foo);

void g(Foo* aFoo) {
  f(aFoo);
  aFoo->DoSomething(); // oops, use after free!
}

What's happening here is that the author is passing a Foo* to f(), without realizing that f() takes a SmartPtr, so the compiler will silently create a SmartPtr<Foo> temporary object, and when f() returns that object gets destroyed and aFoo becomes a dangling pointer, in which case the call to DoSomething turns into a subtle security-sensitive use-after-free bug.

In order to prevent these types of bugs, I have landed bug 1009631 which provides a static analysis that makes it a compile time error to have a constructor such as SmartPtr::SmartPtr in the above example.

The right thing to do with this code is to decide carefully whether you actually mean to provide an implicit conversion. The answer to this question is almost always no! If you answer no, you need to mark the constructor as explicit. If under rare circumstances, you actually intended to provide an implicit conversion, you should mark the constructor as MOZ_IMPLICIT, which doesn't change the meaning of the program in any way and just marks the constructor as being ignored by the static analysis.

What this means to most people is that if your constructor can be invoked with just one parameter, you probably need to mark it as explicit.

In order to avoid burning the tree, if you are a clang user you can add ac_add_options --enable-clang-plugin to your mozconfig and make sure you are using a recent version of clang with the development headers and libraries installed (the binary packages of clang 3.5 from llvm.org should be sufficient for most people.) Otherwise, please make sure to test your patches against the static analysis builders on the try server.

Cheers,
Ehsan
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to