Uploaded image for project: 'Harmony'
  1. Harmony
  2. HARMONY-6405

[classlib][luni] String.equals() is not thread-safe

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 5.0M12
    • 5.0M13
    • None
    • None

    Description

      AFAICT, String.equals() is not thread-safe.

      It includes the following code (wrapped for ease of reference):

      if (count != s.count // 1

      (hashCode != s.hashCode // 2
      && hashCode != 0 // 3
      && s.hashCode != 0)) { //4
      return false; //5

      Suppose both Strings refer to the same sequence of characters, so equals() should return true.
      Suppose the hashCode has not yet been calculated for "s", but it has been calculated for "this".

      At the start: hashCode != s.hashCode and count == s.count

      Line 1 all threads see equality , because count is final.
      Line 2 thread A sees hashCode != s.hashCode, i.e. potentially different Strings
      Thread B then does s.hashCode() and sets s.hashCode !=0
      Line 3 thread A sees hashCode !=0, which is correct
      Line 4 thread A sees s.hashCode !=0, which is different from before
      Line 5 thread A returns false, whereas thread B will return true.

      One possible solution is to fetch the hashCodes into local variables; the values cannot then change unexpectedly.
      Although thread A won't see the updated hashCode for "s", that does not matter, because only non-zero codes matter for this comparison.

      It should also work if the hashCodes were compared after checking for non-zero, but it would be less fragile (and likely quicker) to fetch each value once.

      Attachments

        Issue Links

          Activity

            People

              tellison Tim Ellison
              sebb Sebb
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: