Blob Blame History Raw
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);
         }