Program: 72611
Project: 72611
Buggy source:
/** 
 * Translate the old expression with "row" as indicator to new expression using "dataSetRow" as indicator.
 * @param oldExpression
 * @return
 * @throws DataException
 */
private String prepareTotalExpression(String oldExpression,List columnBindings,String groupName,boolean isCube) throws EngineException {
  try {
    if (oldExpression == null)     return null;
    char[] chars=oldExpression.toCharArray();
    if (chars.length < 8)     return oldExpression;
 else {
      ParseIndicator indicator=new ParseIndicator(0,0,false,false,true,true);
      for (int i=0; i < chars.length; i++) {
        indicator=getParseIndicator(chars,i,indicator.omitNextQuote(),indicator.getCandidateKey1(),indicator.getCandidateKey2());
        i=indicator.getNewIndex();
        if (i >= indicator.getRetrieveSize() + 6) {
          if (indicator.isCandidateKey() && chars[i - indicator.getRetrieveSize() - 6] == 'T' && chars[i - indicator.getRetrieveSize() - 5] == 'o' && chars[i - indicator.getRetrieveSize() - 4] == 't' && chars[i - indicator.getRetrieveSize() - 3] == 'a' && chars[i - indicator.getRetrieveSize() - 2] == 'l' && chars[i - indicator.getRetrieveSize() - 1] == '.') {
            if (i - indicator.getRetrieveSize() - 7 <= 0 || isValidProceeding(chars[i - indicator.getRetrieveSize() - 7])) {
              String firstPart=oldExpression.substring(0,i - indicator.getRetrieveSize() - 6);
              int startIndex=i - indicator.getRetrieveSize() - 6;
              i=advanceToNextValidEncloser(chars,i);
              String secondPart="String_Node_Str";
              String name="String_Node_Str";
              String expr="String_Node_Str";
              if (i < chars.length) {
                int endIndex=i + 1;
                expr=oldExpression.substring(startIndex,endIndex);
                secondPart=prepareTotalExpression(oldExpression.substring(i + 1 - indicator.getRetrieveSize()),columnBindings,groupName,isCube);
              }
 else {
                expr=oldExpression.substring(startIndex);
              }
              boolean shouldAddToList=true;
              for (int j=0; j < columnBindings.size(); j++) {
                IBaseExpression expression=((IBinding)columnBindings.get(j)).getExpression();
                if (expression instanceof IScriptExpression) {
                  if (oldExpression.equals(((IScriptExpression)expression).getText())) {
                    shouldAddToList=false;
                    name=((IBinding)columnBindings.get(j)).getBindingName();
                    break;
                  }
                }
              }
              if (shouldAddToList) {
                name=TOTAL_PREFIX + totalColumnSuffix;
                totalColumnSuffix++;
                ScriptExpression se=new ScriptExpression(expr);
                se.setGroupName(groupName);
                Binding columnBinding=new Binding(name,se);
                columnBindings.add(columnBinding);
              }
              String newExpression=null;
              if (!isCube) {
                newExpression=firstPart + org.eclipse.birt.core.data.ExpressionUtil.createJSRowExpression(name) + secondPart;
              }
 else {
                newExpression=firstPart + org.eclipse.birt.core.data.ExpressionUtil.createJSDataExpression(name) + secondPart;
              }
              return newExpression;
            }
          }
        }
      }
    }
    return oldExpression;
  }
 catch (  DataException e) {
    throw new EngineException(e.getLocalizedMessage());
  }
}

Fixed version (ground truth):
/** 
 * Translate the old expression with "row" as indicator to new expression using "dataSetRow" as indicator.
 * @param oldExpression
 * @return
 * @throws DataException
 */
private String prepareTotalExpression(String oldExpression,List columnBindings,String groupName,boolean isCube) throws EngineException {
  try {
    if (oldExpression == null)     return null;
    char[] chars=oldExpression.toCharArray();
    if (chars.length < 8)     return oldExpression;
 else {
      ParseIndicator indicator=new ParseIndicator(0,0,false,false,true,true);
      for (int i=0; i < chars.length; i++) {
        indicator=getParseIndicator(chars,i,indicator.omitNextQuote(),indicator.getCandidateKey1(),indicator.getCandidateKey2());
        i=indicator.getNewIndex();
        if (i >= indicator.getRetrieveSize() + 6) {
          if (indicator.isCandidateKey() && chars[i - indicator.getRetrieveSize() - 6] == 'T' && chars[i - indicator.getRetrieveSize() - 5] == 'o' && chars[i - indicator.getRetrieveSize() - 4] == 't' && chars[i - indicator.getRetrieveSize() - 3] == 'a' && chars[i - indicator.getRetrieveSize() - 2] == 'l' && chars[i - indicator.getRetrieveSize() - 1] == '.') {
            if (i - indicator.getRetrieveSize() - 7 <= 0 || isValidProceeding(chars[i - indicator.getRetrieveSize() - 7])) {
              String firstPart=oldExpression.substring(0,i - indicator.getRetrieveSize() - 6);
              int startIndex=i - indicator.getRetrieveSize() - 6;
              i=advanceToNextValidEncloser(chars,i);
              String secondPart="String_Node_Str";
              String name="String_Node_Str";
              String expr="String_Node_Str";
              if (i < chars.length) {
                int endIndex=i + 1;
                expr=oldExpression.substring(startIndex,endIndex);
                secondPart=prepareTotalExpression(oldExpression.substring(i + 1 - indicator.getRetrieveSize()),columnBindings,groupName,isCube);
              }
 else {
                expr=oldExpression.substring(startIndex);
              }
              boolean shouldAddToList=true;
              for (int j=0; j < columnBindings.size(); j++) {
                IBaseExpression expression=((IBinding)columnBindings.get(j)).getExpression();
                if (expression instanceof IScriptExpression) {
                  if (oldExpression.equals(((IScriptExpression)expression).getText())) {
                    shouldAddToList=false;
                    name=((IBinding)columnBindings.get(j)).getBindingName();
                    break;
                  }
                }
              }
              if (shouldAddToList) {
                name=TOTAL_PREFIX + totalColumnSuffix;
                totalColumnSuffix++;
                ScriptExpression se=new ScriptExpression(expr);
                se.setGroupName(groupName);
                Binding columnBinding=new Binding(name,se);
                columnBindings.add(columnBinding);
              }
              String newExpression=null;
              if (!isCube) {
                newExpression=firstPart + org.eclipse.birt.core.data.ExpressionUtil.createJSRowExpression(name) + secondPart;
              }
 else {
                newExpression=firstPart + org.eclipse.birt.core.data.ExpressionUtil.createJSDataExpression(name) + secondPart;
              }
              return newExpression;
            }
          }
        }
      }
    }
    return oldExpression;
  }
 catch (  DataException e) {
    throw new EngineException(e);
  }
}