diff -ur yuicompressor-2.4.8.orig/src/org/mozilla/javascript/Decompiler.java yuicompressor-2.4.8/src/org/mozilla/javascript/Decompiler.java
--- yuicompressor-2.4.8.orig/src/org/mozilla/javascript/Decompiler.java 2009-03-22 14:32:26.000000000 +0100
+++ yuicompressor-2.4.8/src/org/mozilla/javascript/Decompiler.java 2017-12-05 17:33:46.070639980 +0100
@@ -166,6 +166,18 @@
appendString('/' + regexp + '/' + flags);
}
+ void addJScriptConditionalComment(String str)
+ {
+ addToken(Token.CONDCOMMENT);
+ appendString(str);
+ }
+
+ void addPreservedComment(String str)
+ {
+ addToken(Token.KEEPCOMMENT);
+ appendString(str);
+ }
+
void addNumber(double n)
{
addToken(Token.NUMBER);
diff -ur yuicompressor-2.4.8.orig/src/org/mozilla/javascript/Parser.java yuicompressor-2.4.8/src/org/mozilla/javascript/Parser.java
--- yuicompressor-2.4.8.orig/src/org/mozilla/javascript/Parser.java 2009-03-22 14:32:24.000000000 +0100
+++ yuicompressor-2.4.8/src/org/mozilla/javascript/Parser.java 2017-12-05 17:33:46.071639969 +0100
@@ -2465,6 +2465,16 @@
reportError("msg.unexpected.eof");
break;
+ case Token.CONDCOMMENT:
+ String condComment = ts.getString();
+ decompiler.addJScriptConditionalComment(condComment);
+ return nf.createString(condComment);
+
+ case Token.KEEPCOMMENT:
+ String keepComment = ts.getString();
+ decompiler.addPreservedComment(keepComment);
+ return nf.createString(keepComment);
+
default:
reportError("msg.syntax");
break;
diff -ur yuicompressor-2.4.8.orig/src/org/mozilla/javascript/Token.java yuicompressor-2.4.8/src/org/mozilla/javascript/Token.java
--- yuicompressor-2.4.8.orig/src/org/mozilla/javascript/Token.java 2009-03-22 14:32:26.000000000 +0100
+++ yuicompressor-2.4.8/src/org/mozilla/javascript/Token.java 2017-12-05 17:33:46.072639958 +0100
@@ -258,7 +258,11 @@
LETEXPR = 157,
WITHEXPR = 158,
DEBUGGER = 159,
- LAST_TOKEN = 159;
+
+ CONDCOMMENT = 160, // JScript conditional comment
+ KEEPCOMMENT = 161, // /*! ... */ comment
+
+ LAST_TOKEN = 161;
public static String name(int token)
{
diff -ur yuicompressor-2.4.8.orig/src/org/mozilla/javascript/TokenStream.java yuicompressor-2.4.8/src/org/mozilla/javascript/TokenStream.java
--- yuicompressor-2.4.8.orig/src/org/mozilla/javascript/TokenStream.java 2009-03-22 14:32:26.000000000 +0100
+++ yuicompressor-2.4.8/src/org/mozilla/javascript/TokenStream.java 2017-12-05 17:33:46.072639958 +0100
@@ -526,7 +526,7 @@
stringBufferTop = 0;
c = getChar();
- strLoop: while (c != quoteChar) {
+ while (c != quoteChar) {
if (c == '\n' || c == EOF_CHAR) {
ungetChar(c);
parser.addError("msg.unterminated.string.lit");
@@ -535,89 +535,47 @@
if (c == '\\') {
// We've hit an escaped character
- int escapeVal;
c = getChar();
+
switch (c) {
- case 'b': c = '\b'; break;
- case 'f': c = '\f'; break;
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
-
- // \v a late addition to the ECMA spec,
- // it is not in Java, so use 0xb
- case 'v': c = 0xb; break;
-
- case 'u':
- // Get 4 hex digits; if the u escape is not
- // followed by 4 hex digits, use 'u' + the
- // literal character sequence that follows.
- int escapeStart = stringBufferTop;
- addToString('u');
- escapeVal = 0;
- for (int i = 0; i != 4; ++i) {
- c = getChar();
- escapeVal = Kit.xDigitToInt(c, escapeVal);
- if (escapeVal < 0) {
- continue strLoop;
- }
+
+ case '\\': // backslash
+ case 'b': // backspace
+ case 'f': // form feed
+ case 'n': // line feed
+ case 'r': // carriage return
+ case 't': // horizontal tab
+ case 'v': // vertical tab
+ case 'd': // octal sequence
+ case 'u': // unicode sequence
+ case 'x': // hexadecimal sequence
+ // Only keep the '\' character for those
+ // characters that need to be escaped...
+ // Don't escape quoting characters...
+ addToString('\\');
addToString(c);
- }
- // prepare for replace of stored 'u' sequence
- // by escape value
- stringBufferTop = escapeStart;
- c = escapeVal;
- break;
- case 'x':
- // Get 2 hex digits, defaulting to 'x'+literal
- // sequence, as above.
- c = getChar();
- escapeVal = Kit.xDigitToInt(c, 0);
- if (escapeVal < 0) {
- addToString('x');
- continue strLoop;
- } else {
- int c1 = c;
- c = getChar();
- escapeVal = Kit.xDigitToInt(c, escapeVal);
- if (escapeVal < 0) {
- addToString('x');
- addToString(c1);
- continue strLoop;
- } else {
- // got 2 hex digits
- c = escapeVal;
- }
- }
- break;
+ break;
- case '\n':
- // Remove line terminator after escape to follow
- // SpiderMonkey and C/C++
- c = getChar();
- continue strLoop;
-
- default:
- if ('0' <= c && c < '8') {
- int val = c - '0';
- c = getChar();
- if ('0' <= c && c < '8') {
- val = 8 * val + c - '0';
- c = getChar();
- if ('0' <= c && c < '8' && val <= 037) {
- // c is 3rd char of octal sequence only
- // if the resulting val <= 0377
- val = 8 * val + c - '0';
- c = getChar();
- }
+ case '\n':
+ // Remove line terminator after escape
+ break;
+
+ default:
+ if (isDigit(c)) {
+ // Octal representation of a character.
+ // Preserve the escaping (see Y! bug #1637286)
+ addToString('\\');
}
- ungetChar(c);
- c = val;
- }
+ addToString(c);
+ break;
}
+
+ } else {
+
+ addToString(c);
}
- addToString(c);
+
c = getChar();
}
@@ -760,16 +718,35 @@
}
if (matchChar('*')) {
boolean lookForSlash = false;
+ StringBuffer sb = new StringBuffer();
for (;;) {
c = getChar();
if (c == EOF_CHAR) {
parser.addError("msg.unterminated.comment");
return Token.ERROR;
- } else if (c == '*') {
+ }
+ sb.append((char) c);
+ if (c == '*') {
lookForSlash = true;
} else if (c == '/') {
if (lookForSlash) {
- continue retry;
+ sb.delete(sb.length()-2, sb.length());
+ String s1 = sb.toString();
+ String s2 = s1.trim();
+ if (s1.startsWith("!")) {
+ // Remove the leading '!'
+ this.string = s1.substring(1);
+ return Token.KEEPCOMMENT;
+ } else if (s2.startsWith("@cc_on") ||
+ s2.startsWith("@if") ||
+ s2.startsWith("@elif") ||
+ s2.startsWith("@else") ||
+ s2.startsWith("@end")) {
+ this.string = s1;
+ return Token.CONDCOMMENT;
+ } else {
+ continue retry;
+ }
}
} else {
lookForSlash = false;
@@ -876,9 +853,9 @@
if (startToken != Token.DIV) Kit.codeBug();
}
- boolean inCharSet = false; // true if inside a '['..']' pair
int c;
- while ((c = getChar()) != '/' || inCharSet) {
+ boolean inClass = false;
+ while ((c = getChar()) != '/' || inClass) {
if (c == '\n' || c == EOF_CHAR) {
ungetChar(c);
throw parser.reportError("msg.unterminated.re.lit");
@@ -887,9 +864,9 @@
addToString(c);
c = getChar();
} else if (c == '[') {
- inCharSet = true;
+ inClass = true;
} else if (c == ']') {
- inCharSet = false;
+ inClass = false;
}
addToString(c);
}