...
This guideline focuses on the potential consequences of this escaping during object construction including race conditions and improper initialization. In general, you must it is important to detect cases where the this reference can leak out beyond the scope of the current context. In particular, be careful when using public variables and methods.
Noncompliant code Example (publish before initialization)
This noncompliant code example publishes the this reference before initialization has concluded, by storing it in a public static class field. Consequently, other threads may obtain a partially initialized Publisher instance.
| Code Block |
|---|
|
class BadPublishPublisher {
public static volatile BadPublishPublisher bppub;
int num;
BadPublishPublisher(int number) {
bppub = this;
// Initialization
this.num = number;
// ...
}
}
|
Also, if the object construction or initialization depends on a security check within the constructor, the security check will be bypassed if an untrusted caller obtains the partially initialized instance (see OBJ04-J. Do not allow partially initialized objects to be accessed for more details).
Noncompliant Code Example (nonvolatile public static field)
This noncompliant code example publishes the this reference in the last statement of the constructor but is still vulnerable because the field bp pub is not declared volatile and has public accessibility.
| Code Block |
|---|
|
class BadPublishPublisher {
public static BadPublish bp Publisher pub;
int num;
BadPublishPublisher(int number) {
// Initialization
this.num = number;
// ...
bppub = this;
}
}
|
Compliant Solution
This compliant solution declares the bp pub field as volatile and reduces the accessibility of the static class field to package-private so that untrusted callers beyond the current package cannot obtain the this instance. More importantly, the constructor publishes the this reference after initialization has concluded.
| Code Block |
|---|
|
class BadPublishPublisher {
static volatile BadPublishPublisher bppub;
BadPublishPublisher(int number) {
// Initialization
this.num = number;
// ...
bppub = this;
}
}
|
If the bp pub field is not declared as volatile initialization statements may be reordered. The Java compiler does not allow declaring the static pub field as final in this case.
Noncompliant Code Example (constructor)
This noncompliant code example defines the ExceptionReporter interface that is implemented by the class ExceptionReporters. This class is useful for reporting exceptions after filtering out any sensitive information (EXC01-J. Use a class dedicated to reporting exceptions). The ExceptionReporters constructor, incorrectly publishes the this reference before construction of the object has concluded. This occurs in the last statement in the constructor (er.setExceptionReporter(this)) which sets the exception reporter. Because it is the last statement in of the constructor, this may be misconstrued as benign.
...
| Code Block |
|---|
|
public class MyExceptionReporter extends ExceptionReporters {
// ...
public void setReporter(ExceptionReporter er) {
super.setExceptionReporter(this);
}
}
|
Noncompliant Code Example (inner class)
| Wiki Markup |
|---|
It is possible for the {{this}} reference to implicitly get leaked outside the scope \[[Goetz 02|AA. Java References#Goetz 02]\]. Consider inner classes that maintain a copy of the {{this}} reference of the outer object. In this noncompliant code example, the constructor for class {{BadExceptionReporter}} uses an anonymous inner class to publish a {{filter()}} method. The problem occurs because the {{this}} reference of the outer class is published by the inner class so that other threads can see it. If the class is subclassed, the issue described in the first noncompliant code example resurfaces. |
| Code Block |
|---|
|
public class BadExceptionReporter implements ExceptionReporter {
public BadExceptionReporter(ExceptionReporter er) {
er.setExceptionReporter(new ExceptionReporters(er) {
public void report(Throwable t) {
filter(t);
}
});
}
public void filter(Throwable t) {
// Filters sensitive exceptions
}
public void report(Throwable exception) {
// Default implementation
}
public void setExceptionReporter(ExceptionReporter er) {
// Sets the reporter
}
}
|
...
| Wiki Markup |
|---|
A {{private}} constructor alongside a {{public}} factory method maycan be used to safely publish the {{filter()}} method from within the constructor \[[Goetz 06|AA. Java References#Goetz 06]\]. |
| Code Block |
|---|
|
public class GoodExceptionReporter implements ExceptionReporter {
private final ExceptionReporters er;
private GoodExceptionReporter(ExceptionReporter excr) {
er = new ExceptionReporters(excr) {
public void report(Throwable t) {
filter(t);
}
};
}
public static GoodExceptionReporter newInstance(ExceptionReporter excr) {
GoodExceptionReporter ger = new GoodExceptionReporter(excr);
excr.setExceptionReporter(ger.er);
return ger;
}
public void filter(Throwable t) { }
public void report(Throwable exception) { }
public void setExceptionReporter(ExceptionReporter er) { }
}
|
Noncompliant Code Example (thread)
| Wiki Markup |
|---|
This noncompliant code example starts a thread from within the constructor. This allows the new thread to access the {{this}} reference of the current object \[[Goetz 02|AA. Java References#Goetz 02], [Goetz 06|AA. Java References#Goetz 06]\]. |
...
| Wiki Markup |
|---|
In this compliant solution, even though the thread is created in the constructor, it is not started unlessuntil theits {{start()}} method is called from somewhere other than the constructor method {{startThread() \[[Goetz 02|AA. Java References#Goetz 02], [Goetz 06|AA. Java References#Goetz 06]\]. |
| Code Block |
|---|
|
public someConstructor() {
thread = new MyThread(this);
}
public void startstartThread() {
thread.start();
}
|
Risk Assessment
...