Program: 25049
Project: 25049
Buggy source:
/** 
 * <p>Let parsing the serialized form of a function definition.</p> <p>The expected syntax is <i>(items between brackets are optional)</i>:</p> <pre>{fctName}([{param1Name} {param1Type}, ...])[ -> {returnType}]</pre> <p> Allowed parameter types and return types should be one the types listed by the UPLOAD section of the TAP recommendation document. These types are listed in the enumeration object   {@link DBType}. However, other types should be accepted like the common database types...but it should be better to not rely on that since the conversion of those types to TAP types should not be exactly what is expected. </p>
 * @param strDefinition	Serialized function definition to parse.
 * @return	The object representation of the given string definition.
 * @throws ParseException	If the given string has a wrong syntax or uses unknown types.
 */
public static FunctionDef parse(final String strDefinition) throws ParseException {
  if (strDefinition == null)   throw new NullPointerException("String_Node_Str");
  Matcher m=fctPattern.matcher(strDefinition);
  if (m.matches()) {
    String fctName=m.group(1);
    DBType returnType=null;
    if (m.group(3) != null) {
      returnType=parseType(m.group(5),(m.group(7) == null) ? DBType.NO_LENGTH : Integer.parseInt(m.group(7)));
      if (returnType == null) {
        returnType=new DBType(DBDatatype.UNKNOWN);
        returnType.type.setCustomType(m.group(4));
      }
    }
    String paramsList=m.group(2);
    FunctionParam[] params=null;
    if (paramsList != null && paramsList.trim().length() > 0) {
      if (!paramsList.matches(fctParamsRegExp))       throw new ParseException("String_Node_Str");
      String[] paramsSplit=paramsList.split("String_Node_Str");
      params=new FunctionParam[paramsSplit.length];
      DBType paramType;
      for (int i=0; i < params.length; i++) {
        m=paramPattern.matcher(paramsSplit[i]);
        if (m.matches()) {
          paramType=parseType(m.group(2),(m.group(4) == null) ? DBType.NO_LENGTH : Integer.parseInt(m.group(4)));
          if (paramType == null) {
            paramType=new DBType(DBDatatype.UNKNOWN);
            paramType.type.setCustomType(m.group(2) + ((m.group(3) == null) ? "String_Node_Str" : m.group(3)));
          }
          params[i]=new FunctionParam(m.group(1),paramType);
        }
 else         throw new ParseException("String_Node_Str" + (i + 1) + "String_Node_Str"+ paramsSplit[i].trim()+ "String_Node_Str");
      }
    }
    return new FunctionDef(fctName,returnType,params);
  }
 else   throw new ParseException("String_Node_Str");
}

Fixed version (ground truth):
/** 
 * <p>Let parsing the serialized form of a function definition.</p> <p>The expected syntax is <i>(items between brackets are optional)</i>:</p> <pre>{fctName}([{param1Name} {param1Type}, ...])[ -> {returnType}]</pre> <p> <em>This function must be able to parse functions as defined by TAPRegExt (section 2.3).</em> Hence, allowed parameter types and return types should be one of the types listed by the UPLOAD section of the TAP recommendation document. These types are listed in the enumeration object   {@link DBType}. However, other types should be accepted like the common database types...but it should be better to not rely on that since the conversion of those types to TAP types should not be exactly what is expected (because depending from the used DBMS); a default interpretation of database types is nevertheless processed by this parser. </p>
 * @param strDefinition	Serialized function definition to parse.
 * @return	The object representation of the given string definition.
 * @throws ParseException	If the given string has a wrong syntax or uses unknown types.
 */
public static FunctionDef parse(final String strDefinition) throws ParseException {
  if (strDefinition == null)   throw new NullPointerException("String_Node_Str");
  Matcher m=fctPattern.matcher(strDefinition);
  if (m.matches()) {
    String fctName=m.group(1);
    DBType returnType=null;
    if (m.group(3) != null) {
      returnType=parseType(m.group(5),(m.group(7) == null) ? DBType.NO_LENGTH : Integer.parseInt(m.group(7)));
      if (returnType == null) {
        returnType=new DBType(DBDatatype.UNKNOWN);
        returnType.type.setCustomType(m.group(4));
      }
    }
    String paramsList=m.group(2);
    FunctionParam[] params=null;
    if (paramsList != null && paramsList.trim().length() > 0) {
      if (!paramsList.matches(fctParamsRegExp))       throw new ParseException("String_Node_Str");
      String[] paramsSplit=paramsList.split("String_Node_Str");
      params=new FunctionParam[paramsSplit.length];
      DBType paramType;
      for (int i=0; i < params.length; i++) {
        m=paramPattern.matcher(paramsSplit[i]);
        if (m.matches()) {
          paramType=parseType(m.group(2),(m.group(4) == null) ? DBType.NO_LENGTH : Integer.parseInt(m.group(4)));
          if (paramType == null) {
            paramType=new DBType(DBDatatype.UNKNOWN);
            paramType.type.setCustomType(m.group(2) + ((m.group(3) == null) ? "String_Node_Str" : m.group(3)));
          }
          params[i]=new FunctionParam(m.group(1),paramType);
        }
 else         throw new ParseException("String_Node_Str" + (i + 1) + "String_Node_Str"+ paramsSplit[i].trim()+ "String_Node_Str");
      }
    }
    return new FunctionDef(fctName,returnType,params);
  }
 else   throw new ParseException("String_Node_Str");
}