Encoding the line and column of a stack trace frame into the line number can exceed the size of 'int' and break StackTraceElement serialization. This patch changes the StackTraceCreator/Deobfuscator to instead, encode the column number of the exception in the JS filename.


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10776 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java b/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
index 2a73797..78a0a5a 100644
--- a/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
+++ b/user/src/com/google/gwt/core/client/impl/StackTraceCreator.java
@@ -33,13 +33,6 @@
   public static final int LINE_NUMBER_UNKNOWN = -1;
 
   /**
-   * Used to encode a (column, line) pair into a line number (since LogRecord only stores line
-   * numbers). We store line, col as line + col * max_line, and use division and modulus to
-   * recover on the server side.
-   */
-  public static final int MAX_LINE_NUMBER = 100000;
-
-  /**
    * This class acts as a deferred-binding hook point to allow more optimal
    * versions to be substituted. This base version simply crawls
    * <code>arguments.callee.caller</code>.
@@ -379,8 +372,8 @@
               col = parseInt(location.substring(lastColon + 1));
           }
         }
-        stackTrace[i] = new StackTraceElement("Unknown", stackElements[0], fileName,
-            line < 0 ? -1 : col * MAX_LINE_NUMBER + line);
+        stackTrace[i] = new StackTraceElement("Unknown", stackElements[0], fileName + "@" + col,
+            line < 0 ? -1 : line);
       }
       e.setStackTrace(stackTrace);
     }
diff --git a/user/src/com/google/gwt/logging/server/StackTraceDeobfuscator.java b/user/src/com/google/gwt/logging/server/StackTraceDeobfuscator.java
index 545b6c4..c5cc302 100644
--- a/user/src/com/google/gwt/logging/server/StackTraceDeobfuscator.java
+++ b/user/src/com/google/gwt/logging/server/StackTraceDeobfuscator.java
@@ -20,7 +20,6 @@
 import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapConsumerV3;
 import com.google.gwt.thirdparty.debugging.sourcemap.SourceMapping;
 import com.google.gwt.thirdparty.debugging.sourcemap.proto.Mapping;
-import com.google.gwt.core.client.impl.StackTraceCreator;
 
 import org.json.JSONObject;
 
@@ -73,8 +72,6 @@
   private Map<String, SourceMapping> sourceMaps =
       new HashMap<String, SourceMapping>();
 
-  private Map<String, Integer> sourceMapPrefixes = new HashMap<String, Integer>();
-
   private Map<String, SymbolMap> symbolMaps =
       new HashMap<String, SymbolMap>();
 
@@ -95,7 +92,7 @@
    *
    * @param lr         the log record to resymbolize
    * @param strongName the GWT permutation strong name
-   * @return the best effort resymbolized log record                                   JJSO
+   * @return the best effort resymbolized log record
    */
   public LogRecord deobfuscateLogRecord(LogRecord lr, String strongName) {
     if (lr.getThrown() != null && strongName != null) {
@@ -175,6 +172,19 @@
       }
     }
 
+    int column = 1;
+    // column information is encoded in filename after '@'
+    if (steFilename != null) {
+      int columnMarkerIndex = steFilename.indexOf("@");
+      if (columnMarkerIndex != -1) {
+        try {
+          column = Integer.parseInt(steFilename.substring(columnMarkerIndex + 1));
+        } catch (NumberFormatException nfe) {
+        }
+        steFilename = steFilename.substring(0, columnMarkerIndex);
+      }
+    }
+
     // anonymous function, try to use <fragmentNum>.js:line:col to lookup function
     if (fragmentId == -1 && steFilename != null) {
       // fragment identifier encoded in filename
@@ -191,16 +201,13 @@
       }
     }
 
+
+    int jsLineNumber = ste.getLineNumber();
+
     // try to refine location via sourcemap
     if (fragmentId != -1) {
       SourceMapping sourceMapping = loadSourceMap(strongName, fragmentId);
       if (sourceMapping != null && ste.getLineNumber() > -1) {
-        int column = 1;
-        int jsLineNumber = ste.getLineNumber();
-        if (jsLineNumber > StackTraceCreator.MAX_LINE_NUMBER) {
-          column = jsLineNumber / StackTraceCreator.MAX_LINE_NUMBER;
-          jsLineNumber = jsLineNumber % StackTraceCreator.MAX_LINE_NUMBER;
-        }
         Mapping.OriginalMapping mappingForLine = sourceMapping
             .getMappingForLine(jsLineNumber, column);
         if (mappingForLine != null) {