Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-1262449

java.lang.String.regionMatches method is not compatible to specification

XMLWordPrintable

    • 1.1
    • sparc
    • solaris_2.5
    • Not verified



      Name: saf@russia Date: 08/07/96


        
      This bug was found by St.Petersburg Java SQE team (by Michael A. Gorshenev).


      ========== Here is the part of language secification =========
      ===== (Pre-Release Version 1.0, Draft 5.2 - July 3, 1996) ====



                            Java API Documentation
                                     1.0.2
                                   Part. 1.16
      "
      REGIONMATCHES

      public boolean
      regionMatches(boolean ignoreCase, int toffset,
      String other, int ooffset, int len)

            Determines if two string regions are equal.

            If toffset or ooffset is negative, or if toffset+length is greater than the length of this string, or if
            ooffset+length is greater than the length of the string argument, then this
            method returns false.

            Parameters:
                  ignoreCase - if true, ignore case when comparing characters
                  toffset - starting offset of the subregion in this string
                  other - string argument
                  ooffset - starting offset of the subregion in the string argument
                  len - the number of characters to compare
            Returns:
                  true if the specified subregion of this string matches the specified subregion of the string
                  argument; false otherwise. Whether the matching is exact or case insensitive depends on the
                  ignoreCase argument.

      "

      "
      20.12.19 public boolean regionMatches(boolean ignoreCase,
      int toffset, String other, int ooffset, int len)
      throws NullPointerException

      A substring of this String object is compared to a substring of the
      argument other. The result is true if these substrings represent
      character sequences that are the same, ignoring case if and only
      if ignoreCase is true. The substring of this String object to be
      compared begins at index toffset and has length len. The substring
      of other to be compared begins at index ooffset and has length len.
      The result is false if and only if at least one of the following is
      true:

            toffset is negative.
            ooffset is negative.
            toffset+len is greater than the length of this String object.
            ooffset+len is greater than the length of the other argument.
            There is some nonnegative integer k less than len such that:
                        this.charAt(toffset+k) != other.charAt(ooffset+k)
            ignoreCase is true and there is some nonnegative integer k
               less than len such that:
                   Character.toLowerCase(this.charAt(toffset+k)) !=
                   Character.toLowerCase(other.charAt(ooffset+k))
                       and:
                   Character.toUpperCase(this.charAt(toffset+k)) !=
                   Character.toUpperCase(other.charAt(ooffset+k))

      If other is null, then a NullPointerException is thrown.
      "


      The bug in Java API 1.0.2 is as follows:

      The method

      java.lang.String.regionMatches(boolean, int, String, int, int)

      may return incorrect value.

      Actually the bug is in assignment "int plim = po + other.count;"
      (please see the source code for the method).
      There must be "int plim = other.offset + other.count;" instead.
         
      =============== Here is the test fragment ===================
            String s1 = "regionMatches() test !!!";
            String s2 = s1.substring(0,20);
            int toffset = 16;
            int ooffset = 16;
            int len = 7;
            /* s2 will be "regionMatches() test"
               s2.length() will be 20
             */
            boolean b=s1.regionMatches(false, toffset,s2,ooffset,len);
            /* ooffset + len > s2.length
               => b must be false
             */
            System.out.println("b="+b); // but will return true!

      =============== Here is the test output =====================
      b=true

      ===== Here is the part of java.lang.String source code ======
          public boolean regionMatches(boolean ignoreCase,
      int toffset,
      String other, int ooffset, int len) {
      char ta[] = value;
      int to = offset + toffset;
      int tlim = offset + count;
      char pa[] = other.value;
      int po = other.offset + ooffset;
      int plim = po + other.count;
      if ((ooffset < 0) || (toffset < 0) || (to + len > tlim) ||
                  (po + len > plim)) {
      return false;
      }
      while (len-- > 0) {
      char c1 = ta[to++];
      char c2 = pa[po++];
      if (c1 == c2)
      continue;
      if (ignoreCase) {
      // If characters don't match but case may be ignored,
      // try converting both characters to uppercase.
      // If the results match, then the comparison scan should
      // continue.
      char u1 = Character.toUpperCase(c1);
      char u2 = Character.toUpperCase(c2);
      if (u1 == u2)
      continue;
      // Unfortunately, conversion to uppercase does not work properly
      // for the Georgian alphabet, which has strange rules about case
      // conversion. So we need to make one last check before
      // exiting.
      if (Character.toLowerCase(u1) == Character.toLowerCase(u2))
      continue;
      }
      return false;
      }
      return true;
          }
      ==============================================================
        

            jrose John Rose
            duke J. Duke
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: