Xerces2-J
  1. Xerces2-J
  2. XERCESJ-1550

An incomplete fix for the NPE bugs in XSSimpleTypeDecl.java

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Invalid
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Other

      Description

      The fix revision 318723 was aimed to remove an NPE bug on the "fPattern" in the method "getLexicalPatterns" of the file "/xerces/java/trunk/src/org/apache/xerces/impl/dv/xs/XSSimpleTypeDecl.java" , but it is incomplete.
      Since the "fPattern" is an class field and also could be null during the run-time execution, it should also be null-checked before being dereferenced in other methods (e.g., Line 1462 in the method " getActualValue").

      The buggy code the proposed missing fixes should be made in is as bellows:

      private Object getActualValue(String content, ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException{

      if (fVariety == VARIETY_ATOMIC) {

      String nvalue;
      if (context==null ||context.needToNormalize())

      { nvalue = normalize(content, fWhiteSpace); } else { nvalue = content; }

      // update normalized value
      validatedInfo.normalizedValue = nvalue;

      // validate special kinds of token, in place of old pattern matching
      if (fPatternType != SPECIAL_PATTERN_NONE) {

      boolean seenErr = false;
      if (fPatternType == SPECIAL_PATTERN_NMTOKEN) { // PATTERN "\\c+" seenErr = !XMLChar.isValidNmtoken(nvalue); }
      else if (fPatternType == SPECIAL_PATTERN_NAME) { // PATTERN "\\i\\c*" seenErr = !XMLChar.isValidName(nvalue); }
      else if (fPatternType == SPECIAL_PATTERN_NCNAME) { // PATTERN "[\\i-[:]][\\c-[:]]*" seenErr = !XMLChar.isValidNCName(nvalue); }
      else if (fPatternType == SPECIAL_PATTERN_INTEGER) { // REVISIT: the pattern is not published yet // we only need to worry about the period '.' // other parts are taken care of by the DecimalDV seenErr = nvalue.indexOf('.') >= 0; }
      if (seenErr) {
      throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1",
      new Object[]{nvalue, SPECIAL_PATTERN_STRING[fPatternType]});
      }
      }

      if ( (fFacetsDefined & FACET_PATTERN ) != 0 ) {
      RegularExpression regex;
      [Line 1462] for (int idx = fPattern.size()1; idx >= 0; idx-) {
      regex = (RegularExpression)fPattern.elementAt(idx);
      if (!regex.matches(nvalue)){
      throw new InvalidDatatypeValueException("cvc-pattern-valid",
      new Object[]{content, regex});
      }
      }
      }

      Object avalue = fDVs[fValidationDV].getActualValue(nvalue, context);

      validatedInfo.actualValue = avalue;

      return avalue;

      } else if (fVariety == VARIETY_LIST) {

      String nvalue;
      if (context==null ||context.needToNormalize()) { nvalue = normalize(content, fWhiteSpace); }

      else

      { nvalue = content; }

      StringTokenizer parsedList = new StringTokenizer(nvalue);
      int countOfTokens = parsedList.countTokens() ;
      Object[] avalue = new Object[countOfTokens];
      XSSimpleTypeDecl[] memberTypes = new XSSimpleTypeDecl[countOfTokens];
      for(int i = 0 ; i < countOfTokens ; i ++){
      // we can't call fItemType.validate(), otherwise checkExtraRules()
      // will be called twice: once in fItemType.validate, once in
      // validate method of this type.
      // so we take two steps to get the actual value:
      // 1. fItemType.getActualValue()
      // 2. fItemType.chekcFacets()
      avalue[i] = fItemType.getActualValue(parsedList.nextToken(), context, validatedInfo);
      if (context.needFacetChecking() &&
      (fItemType.fFacetsDefined != 0 && fItemType.fFacetsDefined != FACET_WHITESPACE))

      { fItemType.checkFacets(validatedInfo); }

      memberTypes[i] = (XSSimpleTypeDecl)validatedInfo.memberType;
      }

      validatedInfo.actualValue = avalue;
      validatedInfo.memberType = null;
      validatedInfo.memberTypes = memberTypes;
      validatedInfo.normalizedValue = nvalue;

      return avalue;

      } else { // (fVariety == VARIETY_UNION)
      for(int i = 0 ; i < fMemberTypes.length; i++) {
      try {
      // we can't call fMemberType[i].validate(), otherwise checkExtraRules()
      // will be called twice: once in fMemberType[i].validate, once in
      // validate method of this type.
      // so we take two steps to get the actual value:
      // 1. fMemberType[i].getActualValue()
      // 2. fMemberType[i].chekcFacets()
      Object aValue = fMemberTypes[i].getActualValue(content, context, validatedInfo);
      if (context.needFacetChecking() &&
      (fMemberTypes[i].fFacetsDefined != 0 && fMemberTypes[i].fFacetsDefined != FACET_WHITESPACE))

      { fMemberTypes[i].checkFacets(validatedInfo); }

      validatedInfo.memberType = fMemberTypes[i];
      return aValue;
      } catch(InvalidDatatypeValueException invalidValue) {
      }
      }

      throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.2",
      new Object[]

      {content, fTypeName}

      );
      }

      }//getActualValue()

        Activity

        Hide
        Michael Glavassevich added a comment -

        If a type has a pattern facet, fPattern will not be null.

        Show
        Michael Glavassevich added a comment - If a type has a pattern facet, fPattern will not be null.

          People

          • Assignee:
            Unassigned
            Reporter:
            Guangtai Liang
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - 10m
              10m
              Remaining:
              Remaining Estimate - 10m
              10m
              Logged:
              Time Spent - Not Specified
              Not Specified

                Development