Program: 54286
Project: 54286
Buggy source:
/** 
 * Adapted from  {@link com.google.gwt.dev.js.rhino.ScriptRuntime#escapeString(String)}. The difference is that we quote with either &quot; or &apos; depending on which one is used less inside the string.
 */
private void printStringLiteral(String value){
  char[] chars=value.toCharArray();
  final int n=chars.length;
  int quoteCount=0;
  int aposCount=0;
  for (int i=0; i < n; ++i) {
switch (chars[i]) {
case '"':
      ++quoteCount;
    break;
case '\'':
  ++aposCount;
break;
}
}
StringBuffer result=new StringBuffer(value.length() + 16);
char quoteChar=(quoteCount < aposCount) ? '"' : '\'';
p.print(quoteChar);
for (int i=0; i < n; ++i) {
char c=chars[i];
if (' ' <= c && c <= '~' && c != quoteChar && c != '\\') {
result.append(c);
continue;
}
int escape=-1;
switch (c) {
case 0:
escape='0';
break;
case '\b':
escape='b';
break;
case '\f':
escape='f';
break;
case '\n':
escape='n';
break;
case '\r':
escape='r';
break;
case '\t':
escape='t';
break;
case '"':
escape='"';
break;
case '\'':
escape='\'';
break;
case '\\':
escape='\\';
break;
}
if (escape >= 0) {
result.append('\\');
result.append((char)escape);
}
 else {
int hexSize;
if (c < 256) {
result.append("String_Node_Str");
hexSize=2;
}
 else {
result.append("String_Node_Str");
hexSize=4;
}
for (int shift=(hexSize - 1) * 4; shift >= 0; shift-=4) {
int digit=0xf & (c >> shift);
result.append(HEX_DIGITS[digit]);
}
}
}
result.append(quoteChar);
escapeClosingTags(result);
p.print(result.toString());
}

Fixed version (ground truth):
/** 
 * Adapted from  {@link com.google.gwt.dev.js.rhino.ScriptRuntime#escapeString(String)}. The difference is that we quote with either &quot; or &apos; depending on which one is used less inside the string.
 */
private void printStringLiteral(String value){
  char[] chars=value.toCharArray();
  final int n=chars.length;
  int quoteCount=0;
  int aposCount=0;
  for (int i=0; i < n; ++i) {
switch (chars[i]) {
case '"':
      ++quoteCount;
    break;
case '\'':
  ++aposCount;
break;
}
}
StringBuffer result=new StringBuffer(value.length() + 16);
char quoteChar=(quoteCount < aposCount) ? '"' : '\'';
p.print(quoteChar);
for (int i=0; i < n; ++i) {
char c=chars[i];
if (' ' <= c && c <= '~' && c != quoteChar && c != '\\') {
result.append(c);
continue;
}
int escape=-1;
switch (c) {
case '\b':
escape='b';
break;
case '\f':
escape='f';
break;
case '\n':
escape='n';
break;
case '\r':
escape='r';
break;
case '\t':
escape='t';
break;
case '"':
escape='"';
break;
case '\'':
escape='\'';
break;
case '\\':
escape='\\';
break;
}
if (escape >= 0) {
result.append('\\');
result.append((char)escape);
}
 else {
if (c < ' ' && (i == n - 1 || chars[i + 1] < '0' || chars[i + 1] > '9')) {
result.append('\\');
if (c > 0x7) {
result.append((char)('0' + (0x7 & (c >> 3))));
}
result.append((char)('0' + (0x7 & c)));
}
 else {
int hexSize;
if (c < 256) {
result.append("String_Node_Str");
hexSize=2;
}
 else {
result.append("String_Node_Str");
hexSize=4;
}
for (int shift=(hexSize - 1) * 4; shift >= 0; shift-=4) {
int digit=0xf & (c >> shift);
result.append(HEX_DIGITS[digit]);
}
}
}
}
result.append(quoteChar);
escapeClosingTags(result);
p.print(result.toString());
}