Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: added NCE/CS

...

In general, you must 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

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 instance.

Code Block
bgColor#FFcccc

class BadPublish {
  public static BadPublish bp;
  int num;

  BadPublish(int number) {
    bp = 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 can obtain the partially initialized instance (see OBJ04-J. Do not allow partially initialized objects to be accessed for more details).

Compliant Solution

This compliant solution 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
bgColor#ccccff

class BadPublish {
  static BadPublish bp;

  BadPublish(int number) {
    // Initialization 
    this.num = number;
    // ...
    bp = this;
  }
}

Noncompliant Code Example

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 the constructor, this may be misconstrued as benign.

...

This erroneous behavior results from the race condition between an oncoming exception and the initialization of the subclass. If the exception comes too soon, it finds the subclass in a compromised state. This behavior is even more counter intuitive because logger is declared final and is not expected to contain an unintialized value.

Compliant Solution

This compliant solution declares the setReporter() method in class MyExceptionReporter. It explicitly calls the superclass's setExceptionReporter() method, publishing a reference to its own Class object. It is not permissible to publish the reference in the constructor for MyExceptionReporter for reasons noted earlier in the noncompliant code example.

...

Code Block
bgColor#FFcccc
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 
  }
}

Compliant Solution

Wiki Markup
A {{private}} constructor alongside a {{public}} factory method may be used to publish the {{filter()}} method from within the constructor \[[Goetz 06|AA. Java References#Goetz 06]\].

...

Code Block
bgColor#FFcccc
public someConstructor() {
  thread = new MyThread(this);
  thread.start();
}

Compliant Solution

Wiki Markup
In this compliant solution, even though the thread is created in the constructor, it is not started unless the {{start()}} method is called from somewhere other than the constructor \[[Goetz 02|AA. Java References#Goetz 02], [Goetz 06|AA. Java References#Goetz 06]\].

...