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