Program: 54415
Project: 54415
Buggy source:
/** 
 * This function parses a "localized" text into a <code>double</code>. It needs to handle locale specific decimal, grouping, exponent and digit.
 * @param text the text that need to be parsed
 * @param pos in/out parsing position. in case of failure, this shouldn't bechanged
 * @return double value, could be 0.0 if nothing can be parsed
 */
private double parseNumber(String text,int[] pos){
  double ret;
  boolean sawDecimal=false;
  boolean sawExponent=false;
  boolean sawDigit=false;
  int scale=1;
  String decimal=isCurrencyFormat ? numberConstants.monetarySeparator() : numberConstants.decimalSeparator();
  String grouping=isCurrencyFormat ? numberConstants.monetaryGroupingSeparator() : numberConstants.groupingSeparator();
  String exponentChar=numberConstants.exponentialSymbol();
  StringBuffer normalizedText=new StringBuffer();
  for (; pos[0] < text.length(); ++pos[0]) {
    char ch=text.charAt(pos[0]);
    int digit=getDigit(ch);
    if (digit >= 0 && digit <= 9) {
      normalizedText.append((char)(digit + '0'));
      sawDigit=true;
    }
 else     if (ch == decimal.charAt(0)) {
      if (sawDecimal || sawExponent) {
        break;
      }
      normalizedText.append('.');
      sawDecimal=true;
    }
 else     if (ch == grouping.charAt(0)) {
      if (sawDecimal || sawExponent) {
        break;
      }
      continue;
    }
 else     if (ch == exponentChar.charAt(0)) {
      if (sawExponent) {
        break;
      }
      normalizedText.append('E');
      sawExponent=true;
    }
 else     if (ch == '+' || ch == '-') {
      normalizedText.append(ch);
    }
 else     if (ch == numberConstants.percent().charAt(0)) {
      if (scale != 1) {
        break;
      }
      scale=100;
      if (sawDigit) {
        ++pos[0];
        break;
      }
    }
 else     if (ch == numberConstants.perMill().charAt(0)) {
      if (scale != 1) {
        break;
      }
      scale=1000;
      if (sawDigit) {
        ++pos[0];
        break;
      }
    }
 else {
      break;
    }
  }
  ret=Double.parseDouble(normalizedText.toString());
  ret=ret / scale;
  return ret;
}

Fixed version (ground truth):
/** 
 * This function parses a "localized" text into a <code>double</code>. It needs to handle locale specific decimal, grouping, exponent and digit.
 * @param text the text that need to be parsed
 * @param pos in/out parsing position. in case of failure, this shouldn't bechanged
 * @return double value, could be 0.0 if nothing can be parsed
 */
private double parseNumber(String text,int[] pos){
  double ret;
  boolean sawDecimal=false;
  boolean sawExponent=false;
  boolean sawDigit=false;
  int scale=1;
  String decimal=isCurrencyFormat ? numberConstants.monetarySeparator() : numberConstants.decimalSeparator();
  String grouping=isCurrencyFormat ? numberConstants.monetaryGroupingSeparator() : numberConstants.groupingSeparator();
  String exponentChar=numberConstants.exponentialSymbol();
  StringBuffer normalizedText=new StringBuffer();
  for (; pos[0] < text.length(); ++pos[0]) {
    char ch=text.charAt(pos[0]);
    int digit=getDigit(ch);
    if (digit >= 0 && digit <= 9) {
      normalizedText.append((char)(digit + '0'));
      sawDigit=true;
    }
 else     if (ch == decimal.charAt(0)) {
      if (sawDecimal || sawExponent) {
        break;
      }
      normalizedText.append('.');
      sawDecimal=true;
    }
 else     if (ch == grouping.charAt(0)) {
      if (sawDecimal || sawExponent) {
        break;
      }
      continue;
    }
 else     if (ch == exponentChar.charAt(0)) {
      if (sawExponent) {
        break;
      }
      normalizedText.append('E');
      sawExponent=true;
    }
 else     if (ch == '+' || ch == '-') {
      normalizedText.append(ch);
    }
 else     if (ch == numberConstants.percent().charAt(0)) {
      if (scale != 1) {
        break;
      }
      scale=100;
      if (sawDigit) {
        ++pos[0];
        break;
      }
    }
 else     if (ch == numberConstants.perMill().charAt(0)) {
      if (scale != 1) {
        break;
      }
      scale=1000;
      if (sawDigit) {
        ++pos[0];
        break;
      }
    }
 else {
      break;
    }
  }
  try {
    ret=Double.parseDouble(normalizedText.toString());
  }
 catch (  NumberFormatException e) {
    throw new NumberFormatException(text);
  }
  ret=ret / scale;
  return ret;
}