Revision: 5984 Author: [email protected] Date: Thu Aug 20 13:57:35 2009 Log: Updates XML escaping for SOYC. Previously, some UTF-8 characters slipped through that are not allowed in XML, which caused the dashboard to crash. This fixes the problem.
http://code.google.com/p/google-web-toolkit/source/detail?r=5984 Modified: /trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/SizeMapRecorder.java /trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorder.java ======================================= --- /trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/SizeMapRecorder.java Tue Aug 4 09:54:58 2009 +++ /trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/SizeMapRecorder.java Thu Aug 20 13:57:35 2009 @@ -55,6 +55,87 @@ } } + /** + * Escapes '&', '<', '>', '"', and '\'' to their XML entity equivalents. + */ + public static String escapeXml(String unescaped) { + StringBuilder builder = new StringBuilder(); + escapeXml(unescaped, 0, unescaped.length(), true, builder); + return builder.toString(); + } + + /** + * Escapes '&', '<', '>', '"', and optionally ''' to their XML entity + * equivalents. The portion of the input string between start (inclusive) and + * end (exclusive) is scanned. The output is appended to the given + * StringBuilder. + * + * @param code the input String + * @param start the first character position to scan. + * @param end the character position following the last character to scan. + * @param quoteApostrophe if true, the ' character is quoted as + * &apos; + * @param builder a StringBuilder to be appended with the output. + */ + public static void escapeXml(String code, int start, int end, + boolean quoteApostrophe, StringBuilder builder) { + int lastIndex = 0; + int len = end - start; + char[] c = new char[len]; + + code.getChars(start, end, c, 0); + for (int i = 0; i < len; i++) { + if ((c[i] >= '\uD800') && (c[i] <= '\uDBFF')) { + builder.append(c, lastIndex, i - lastIndex); + builder.append("(non-valid utf-8 character)"); + lastIndex = i + 1; + break; + } else if ((c[i] >= '\uDC00') && (c[i] <= '\uDFFF')) { + builder.append(c, lastIndex, i - lastIndex); + builder.append("(non-valid utf-8 character)"); + lastIndex = i + 1; + break; + } else if (c[i] == '\0') { + builder.append(c, lastIndex, i - lastIndex); + builder.append("(null)"); + lastIndex = i + 1; + break; + } else if (c[i] == '\uffff') { + builder.append(c, lastIndex, i - lastIndex); + builder.append("(uffff)"); + lastIndex = i + 1; + break; + } else if (c[i] == '\ufffe') { + builder.append(c, lastIndex, i - lastIndex); + builder.append("(ufffe)"); + lastIndex = i + 1; + } else if (c[i] == '&') { + builder.append(c, lastIndex, i - lastIndex); + builder.append("&"); + lastIndex = i + 1; + } else if (c[i] == '>') { + builder.append(c, lastIndex, i - lastIndex); + builder.append(">"); + lastIndex = i + 1; + } else if (c[i] == '<') { + builder.append(c, lastIndex, i - lastIndex); + builder.append("<"); + lastIndex = i + 1; + } else if (c[i] == '\"') { + builder.append(c, lastIndex, i - lastIndex); + builder.append("""); + lastIndex = i + 1; + } else if (c[i] == '\'') { + if (quoteApostrophe) { + builder.append(c, lastIndex, i - lastIndex); + builder.append("'"); + lastIndex = i + 1; + } + } + } + builder.append(c, lastIndex, len - lastIndex); + } + public static void recordMap(TreeLogger logger, OutputStream out, SizeBreakdown[] sizeBreakdowns, JavaToJavaScriptMap jjsmap, Map<JsName, String> obfuscateMap) throws IOException { @@ -72,8 +153,8 @@ int size = sizeMapEntry.getValue(); TypedProgramReference typedRef = typedProgramReference(name, jjsmap, obfuscateMap); - writer.append(" <size " + "type=\"" + Util.escapeXml(typedRef.type) - + "\" " + "ref=\"" + Util.escapeXml(typedRef.description) + "\" " + writer.append(" <size " + "type=\"" + escapeXml(typedRef.type) + + "\" " + "ref=\"" + escapeXml(typedRef.description) + "\" " + "size=\"" + size + "\"/>\n"); } writer.append("</sizemap>\n"); ======================================= --- /trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorder.java Mon Jun 1 10:40:23 2009 +++ /trunk/dev/core/src/com/google/gwt/core/ext/soyc/impl/StoryRecorder.java Thu Aug 20 13:57:35 2009 @@ -310,7 +310,7 @@ builder.append("\"/>\n</story>\n"); } else { builder.append("\">"); - Util.escapeXml(jsCode, start, end, false, builder); + SizeMapRecorder.escapeXml(jsCode, start, end, false, builder); builder.append("</storyref>\n</story>\n"); } } --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
