AbstractAccessReferenceMap.addDirectReference not invariant


From filippo....@gmail.com on April 11, 2014 12:48:34

Implementation of addDirectReference may return a different value in case of concurrent calls for the same "direct" value.

1. public <T> K addDirectReference(T direct) {
2. if ( dtoi.keySet().contains( direct ) ) {
3. return dtoi.get( direct );
4. }
5. K indirect = getUniqueReference();
6. itod.put(indirect, direct);
7. dtoi.put(direct, indirect);
8. return indirect;
9. }

If two threads concurrently call addDirectReference, the indirect value returned may be different (can be verified by putting a sleep within the above method). As a result, itod will contain both the indirect values whereas dtoi will contain only the last one. As the indirect value is returned, one of the two threads will have a value that cannot be obtained anymore from addDirectReference.

Although this is not strictly a bug, stating that the class is thread-safe leads to believe that its methods are invariant unless told otherwise. Multi-threaded scenarios where is expected that a given direct id always returns the same indirect id will experience erratic behaviour from this call, which will "mostly" return the same id but not always.

Whether this is considered a bug or not is yours to decide. If it's not, then please put the proper way to use addDirectReference and getDirectReference into the documentation.

Original issue: http://code.google.com/p/owasp-esapi-java/issues/detail?id=325






Max Gelman