Thu, 22 Dec 2016 16:21:25 -0800
Merge
.hgtags | file | annotate | diff | comparison | revisions |
1.1 --- a/.hgtags Tue Dec 20 15:24:55 2016 -0800 1.2 +++ b/.hgtags Thu Dec 22 16:21:25 2016 -0800 1.3 @@ -632,6 +632,10 @@ 1.4 56b0df415b570e31dc0b97d4a1c8f28b85240089 jdk8u102-b13 1.5 0549bf2f507dae59bfcd7d11e038cdc62376fee7 jdk8u102-b14 1.6 d86027f25a9aa960d69cf3a524588a873ae888f5 jdk8u102-b31 1.7 +1b511d4e93e7128ccb7100110ab6604eb2838afa jdk8u102-b32 1.8 +3d4b72198b23108f93ccf36b8d9275cc3b40ee1e jdk8u102-b33 1.9 +8bde2f8474d372de6a3425affd38de506aa56a51 jdk8u102-b34 1.10 +e64f16f8a585332086127b4f24b79e6c83bee530 jdk8u102-b35 1.11 90f493bfe1faca0573844fdd2497070c8b224d76 jdk8u111-b00 1.12 085fd7e08f4855f134a8048251c4535ddde1feee jdk8u111-b01 1.13 f66a535fb6b3b41419c987cc90407507a64712b2 jdk8u111-b02 1.14 @@ -663,6 +667,21 @@ 1.15 b353281f73db9617d993353e468342d3420c29f1 jdk8u112-b14 1.16 6116c6644be0c85556931aaeb9b4f2dbc9c79157 jdk8u112-b15 1.17 ee37eafc48cb6fb20cb6c1e31cfecfe1ccc800da jdk8u112-b16 1.18 +de1c3df992adb0c704005583210d1ed6dac758cd jdk8u112-b31 1.19 +5710d574a99aeff3600c49a4aed34fa1b373f7b8 jdk8u121-b00 1.20 +ab5d32d8cf5f6d81482692f801385a869b2d83c1 jdk8u121-b01 1.21 +e260d46661d2da3ede78aae434d5420acce99950 jdk8u121-b02 1.22 +0acfd50d67d98259a25fbd51129b763bab56d068 jdk8u121-b03 1.23 +29a08aff06088cad98dafddef7628b51e324fcae jdk8u121-b04 1.24 +a933635275c33e37c9403767d600a12b9ee71df7 jdk8u121-b05 1.25 +dc1dd2e6cf8e094c4a8437d54ebc7bac1f7ab964 jdk8u121-b06 1.26 +6cd0cd4078e9ec8ad9fa167cabf9c671ed21fc66 jdk8u121-b07 1.27 +8efc10efbfe137ed5de6bf55875fdafd25bb6a1b jdk8u121-b08 1.28 +57a26fe61f2b435332c0697e92965a22246cd143 jdk8u121-b09 1.29 +53c94a674d6076ff390c62a7682ea0e87a893cdc jdk8u121-b10 1.30 +b634abfcd98fb8b201da9208e398ea17cabd2b32 jdk8u121-b11 1.31 +7fc347da372c8c4e5530a7fa32084b5dbc4ee8b6 jdk8u121-b12 1.32 +f634736433d9fc1cffbdc55611f97ecb2cd44059 jdk8u121-b13 1.33 9a9ce479b92f1b4d9d436fb857d70c3d2b59a20c jdk8u122-b00 1.34 85d9e434701cc7112aaf965b0f5ee4b31ab2a445 jdk8u122-b01 1.35 2baeb96fa198f75e9bd50a5f5ef4a19be6cfbc4e jdk8u122-b02
2.1 --- a/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Tue Dec 20 15:24:55 2016 -0800 2.2 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java Thu Dec 22 16:21:25 2016 -0800 2.3 @@ -1,5 +1,5 @@ 2.4 /* 2.5 - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. 2.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 * 2.9 * This code is free software; you can redistribute it and/or modify it 2.10 @@ -38,6 +38,7 @@ 2.11 import com.sun.tools.javac.file.JavacFileManager; 2.12 import com.sun.tools.javac.util.Context; 2.13 import com.sun.tools.javac.util.StringUtils; 2.14 +import com.sun.tools.javadoc.JavaScriptScanner; 2.15 import com.sun.tools.javadoc.RootDocImpl; 2.16 2.17 /** 2.18 @@ -181,6 +182,11 @@ 2.19 public Set<String> doclintOpts = new LinkedHashSet<String>(); 2.20 2.21 /** 2.22 + * Whether or not to check for JavaScript in doc comments. 2.23 + */ 2.24 + private boolean allowScriptInComments; 2.25 + 2.26 + /** 2.27 * Unique Resource Handler for this package. 2.28 */ 2.29 public final MessageRetriever standardmessage; 2.30 @@ -283,8 +289,11 @@ 2.31 doclintOpts.add(null); 2.32 } else if (opt.startsWith("-xdoclint:")) { 2.33 doclintOpts.add(opt.substring(opt.indexOf(":") + 1)); 2.34 + } else if (opt.equals("--allow-script-in-comments")) { 2.35 + allowScriptInComments = true; 2.36 } 2.37 } 2.38 + 2.39 if (root.specifiedClasses().length > 0) { 2.40 Map<String,PackageDoc> map = new HashMap<String,PackageDoc>(); 2.41 PackageDoc pd; 2.42 @@ -301,9 +310,30 @@ 2.43 2.44 if (root instanceof RootDocImpl) { 2.45 ((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames()); 2.46 + JavaScriptScanner jss = ((RootDocImpl) root).initJavaScriptScanner(isAllowScriptInComments()); 2.47 + if (jss != null) { 2.48 + // In a more object-oriented world, this would be done by methods on the Option objects. 2.49 + // Note that -windowtitle silently removes any and all HTML elements, and so does not need 2.50 + // to be handled here. 2.51 + checkJavaScript(jss, "-header", header); 2.52 + checkJavaScript(jss, "-footer", footer); 2.53 + checkJavaScript(jss, "-top", top); 2.54 + checkJavaScript(jss, "-bottom", bottom); 2.55 + checkJavaScript(jss, "-doctitle", doctitle); 2.56 + checkJavaScript(jss, "-packagesheader", packagesheader); 2.57 + } 2.58 } 2.59 } 2.60 2.61 + private void checkJavaScript(JavaScriptScanner jss, final String opt, String value) { 2.62 + jss.parse(value, new JavaScriptScanner.Reporter() { 2.63 + public void report() { 2.64 + root.printError(getText("doclet.JavaScript_in_option", opt)); 2.65 + throw new FatalError(); 2.66 + } 2.67 + }); 2.68 + } 2.69 + 2.70 /** 2.71 * Returns the "length" of a given option. If an option takes no 2.72 * arguments, its length is one. If it takes one argument, it's 2.73 @@ -337,7 +367,8 @@ 2.74 option.equals("-nonavbar") || 2.75 option.equals("-nooverview") || 2.76 option.equals("-xdoclint") || 2.77 - option.startsWith("-xdoclint:")) { 2.78 + option.startsWith("-xdoclint:") || 2.79 + option.equals("--allow-script-in-comments")) { 2.80 return 1; 2.81 } else if (option.equals("-help")) { 2.82 // Uugh: first, this should not be hidden inside optionLength, 2.83 @@ -595,4 +626,13 @@ 2.84 public Content newContent() { 2.85 return new ContentBuilder(); 2.86 } 2.87 + 2.88 + /** 2.89 + * Returns whether or not to allow JavaScript in comments. 2.90 + * Default is off; can be set true from a command line option. 2.91 + * @return the allowScriptInComments 2.92 + */ 2.93 + public boolean isAllowScriptInComments() { 2.94 + return allowScriptInComments; 2.95 + } 2.96 }
3.1 --- a/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Tue Dec 20 15:24:55 2016 -0800 3.2 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDoclet.java Thu Dec 22 16:21:25 2016 -0800 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -190,6 +190,8 @@ 3.11 } 3.12 } catch (IOException e) { 3.13 throw new DocletAbortException(e); 3.14 + } catch (FatalError fe) { 3.15 + throw fe; 3.16 } catch (DocletAbortException de) { 3.17 throw de; 3.18 } catch (Exception e) {
4.1 --- a/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Tue Dec 20 15:24:55 2016 -0800 4.2 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/markup/HtmlWriter.java Thu Dec 22 16:21:25 2016 -0800 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -164,7 +164,9 @@ 4.11 4.12 public final Content descfrmInterfaceLabel; 4.13 4.14 - private final Writer writer; 4.15 + private final DocFile file; 4.16 + 4.17 + private Writer writer; 4.18 4.19 private Content script; 4.20 4.21 @@ -180,7 +182,7 @@ 4.22 */ 4.23 public HtmlWriter(Configuration configuration, DocPath path) 4.24 throws IOException, UnsupportedEncodingException { 4.25 - writer = DocFile.createFileForOutput(configuration, path).openWriter(); 4.26 + file = DocFile.createFileForOutput(configuration, path); 4.27 this.configuration = configuration; 4.28 this.memberDetailsListPrinted = false; 4.29 profileTableHeader = new String[] { 4.30 @@ -239,6 +241,7 @@ 4.31 } 4.32 4.33 public void write(Content c) throws IOException { 4.34 + writer = file.openWriter(); 4.35 c.write(writer, true); 4.36 } 4.37
5.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java Tue Dec 20 15:24:55 2016 -0800 5.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/AbstractDoclet.java Thu Dec 22 16:21:25 2016 -0800 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -83,6 +83,8 @@ 5.11 } catch (Configuration.Fault f) { 5.12 root.printError(f.getMessage()); 5.13 return false; 5.14 + } catch (FatalError fe) { 5.15 + return false; 5.16 } catch (DocletAbortException e) { 5.17 Throwable cause = e.getCause(); 5.18 if (cause != null) {
6.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java Tue Dec 20 15:24:55 2016 -0800 6.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/builders/AbstractBuilder.java Thu Dec 22 16:21:25 2016 -0800 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -140,7 +140,14 @@ 6.11 configuration.root.printError("Unknown element: " + component); 6.12 throw new DocletAbortException(e); 6.13 } catch (InvocationTargetException e) { 6.14 - throw new DocletAbortException(e.getCause()); 6.15 + Throwable cause = e.getCause(); 6.16 + if (cause instanceof FatalError) { 6.17 + throw (FatalError) cause; 6.18 + } else if (cause instanceof DocletAbortException) { 6.19 + throw (DocletAbortException) cause; 6.20 + } else { 6.21 + throw new DocletAbortException(cause); 6.22 + } 6.23 } catch (Exception e) { 6.24 e.printStackTrace(); 6.25 configuration.root.printError("Exception " +
7.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Tue Dec 20 15:24:55 2016 -0800 7.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Thu Dec 22 16:21:25 2016 -0800 7.3 @@ -29,6 +29,8 @@ 7.4 doclet.Building_Tree=Building tree for all the packages and classes... 7.5 doclet.Building_Index=Building index for all the packages and classes... 7.6 doclet.Building_Index_For_All_Classes=Building index for all classes... 7.7 +doclet.JavaScript_in_option=Argument for {0} contains JavaScript.\n\ 7.8 +Use --allow-script-in-comments to allow use of JavaScript. 7.9 doclet.sourcetab_warning=The argument for -sourcetab must be an integer greater than 0. 7.10 doclet.Packages=Packages 7.11 doclet.Profiles=Profiles
8.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties Tue Dec 20 15:24:55 2016 -0800 8.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_ja.properties Thu Dec 22 16:21:25 2016 -0800 8.3 @@ -27,6 +27,7 @@ 8.4 doclet.Building_Tree=\u5168\u30D1\u30C3\u30B1\u30FC\u30B8\u3068\u30AF\u30E9\u30B9\u306E\u968E\u5C64\u30C4\u30EA\u30FC\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059... 8.5 doclet.Building_Index=\u5168\u30D1\u30C3\u30B1\u30FC\u30B8\u3068\u30AF\u30E9\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059... 8.6 doclet.Building_Index_For_All_Classes=\u5168\u30AF\u30E9\u30B9\u306E\u30A4\u30F3\u30C7\u30C3\u30AF\u30B9\u3092\u4F5C\u6210\u3057\u3066\u3044\u307E\u3059... 8.7 +doclet.JavaScript_in_option={0}\u306E\u5F15\u6570\u306BJavaScript\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u3059\u3002\n--allow-script-in-comments\u3092\u4F7F\u7528\u3057\u3066\u3001JavaScript\u306E\u4F7F\u7528\u3092\u8A31\u53EF\u3057\u3066\u304F\u3060\u3055\u3044\u3002 8.8 doclet.sourcetab_warning=-sourcetab\u306E\u5F15\u6570\u306F0\u3088\u308A\u5927\u304D\u3044\u6574\u6570\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002 8.9 doclet.Packages=\u30D1\u30C3\u30B1\u30FC\u30B8 8.10 doclet.Profiles=\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB
9.1 --- a/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties Tue Dec 20 15:24:55 2016 -0800 9.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets_zh_CN.properties Thu Dec 22 16:21:25 2016 -0800 9.3 @@ -27,6 +27,7 @@ 9.4 doclet.Building_Tree=\u6B63\u5728\u6784\u5EFA\u6240\u6709\u7A0B\u5E8F\u5305\u548C\u7C7B\u7684\u6811... 9.5 doclet.Building_Index=\u6B63\u5728\u6784\u5EFA\u6240\u6709\u7A0B\u5E8F\u5305\u548C\u7C7B\u7684\u7D22\u5F15... 9.6 doclet.Building_Index_For_All_Classes=\u6B63\u5728\u6784\u5EFA\u6240\u6709\u7C7B\u7684\u7D22\u5F15... 9.7 +doclet.JavaScript_in_option={0} \u7684\u53C2\u6570\u5305\u542B JavaScript\u3002\n\u4F7F\u7528 --allow-script-in-comments \u53EF\u5141\u8BB8\u4F7F\u7528 JavaScript\u3002 9.8 doclet.sourcetab_warning=-sourcetab \u7684\u53C2\u6570\u5FC5\u987B\u662F\u5927\u4E8E 0 \u7684\u6574\u6570\u3002 9.9 doclet.Packages=\u7A0B\u5E8F\u5305 9.10 doclet.Profiles=\u914D\u7F6E\u6587\u4EF6
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/FatalError.java Thu Dec 22 16:21:25 2016 -0800 10.3 @@ -0,0 +1,39 @@ 10.4 +/* 10.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 10.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.7 + * 10.8 + * This code is free software; you can redistribute it and/or modify it 10.9 + * under the terms of the GNU General Public License version 2 only, as 10.10 + * published by the Free Software Foundation. Oracle designates this 10.11 + * particular file as subject to the "Classpath" exception as provided 10.12 + * by Oracle in the LICENSE file that accompanied this code. 10.13 + * 10.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 10.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 10.17 + * version 2 for more details (a copy is included in the LICENSE file that 10.18 + * accompanied this code). 10.19 + * 10.20 + * You should have received a copy of the GNU General Public License version 10.21 + * 2 along with this work; if not, write to the Free Software Foundation, 10.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 10.23 + * 10.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 10.25 + * or visit www.oracle.com if you need additional information or have any 10.26 + * questions. 10.27 + */ 10.28 + 10.29 +package com.sun.tools.doclets.internal.toolkit.util; 10.30 + 10.31 +/** 10.32 + * <p><b>This is NOT part of any supported API. 10.33 + * If you write code that depends on this, you do so at your own risk. 10.34 + * This code and its internal interfaces are subject to change or 10.35 + * deletion without notice.</b> 10.36 + */ 10.37 +@Deprecated 10.38 +public class FatalError extends Error { 10.39 + private static final long serialVersionUID = -9131058909576418984L; 10.40 + 10.41 + public FatalError() { } 10.42 +}
11.1 --- a/src/share/classes/com/sun/tools/doclint/Checker.java Tue Dec 20 15:24:55 2016 -0800 11.2 +++ b/src/share/classes/com/sun/tools/doclint/Checker.java Thu Dec 22 16:21:25 2016 -0800 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 11.6 + * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -126,7 +126,7 @@ 11.11 } 11.12 } 11.13 11.14 - private Deque<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well 11.15 + private final Deque<TagStackItem> tagStack; // TODO: maybe want to record starting tree as well 11.16 private HtmlTag currHeaderTag; 11.17 11.18 private final int implicitHeaderLevel; 11.19 @@ -401,7 +401,16 @@ 11.20 break; 11.21 11.22 case OTHER: 11.23 - env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName); 11.24 + switch (t) { 11.25 + case SCRIPT: 11.26 + // <script> may or may not be allowed, depending on --allow-script-in-comments 11.27 + // but we allow it here, and rely on a separate scanner to detect all uses 11.28 + // of JavaScript, including <script> tags, and use in attributes, etc. 11.29 + break; 11.30 + 11.31 + default: 11.32 + env.messages.error(HTML, tree, "dc.tag.not.allowed", treeName); 11.33 + } 11.34 return; 11.35 } 11.36 11.37 @@ -519,22 +528,27 @@ 11.38 if (!first) 11.39 env.messages.error(HTML, tree, "dc.attr.repeated", name); 11.40 } 11.41 - AttrKind k = currTag.getAttrKind(name); 11.42 - switch (k) { 11.43 - case OK: 11.44 - break; 11.45 11.46 - case INVALID: 11.47 - env.messages.error(HTML, tree, "dc.attr.unknown", name); 11.48 - break; 11.49 + // for now, doclint allows all attribute names beginning with "on" as event handler names, 11.50 + // without checking the validity or applicability of the name 11.51 + if (!name.toString().startsWith("on")) { 11.52 + AttrKind k = currTag.getAttrKind(name); 11.53 + switch (k) { 11.54 + case OK: 11.55 + break; 11.56 11.57 - case OBSOLETE: 11.58 - env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete", name); 11.59 - break; 11.60 + case INVALID: 11.61 + env.messages.error(HTML, tree, "dc.attr.unknown", name); 11.62 + break; 11.63 11.64 - case USE_CSS: 11.65 - env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete.use.css", name); 11.66 - break; 11.67 + case OBSOLETE: 11.68 + env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete", name); 11.69 + break; 11.70 + 11.71 + case USE_CSS: 11.72 + env.messages.warning(ACCESSIBILITY, tree, "dc.attr.obsolete.use.css", name); 11.73 + break; 11.74 + } 11.75 } 11.76 11.77 if (attr != null) { 11.78 @@ -643,6 +657,9 @@ 11.79 } 11.80 11.81 private void checkURI(AttributeTree tree, String uri) { 11.82 + // allow URIs beginning with javascript:, which would otherwise be rejected by the URI API. 11.83 + if (uri.startsWith("javascript:")) 11.84 + return; 11.85 try { 11.86 URI u = new URI(uri); 11.87 } catch (URISyntaxException e) {
12.1 --- a/src/share/classes/com/sun/tools/doclint/HtmlTag.java Tue Dec 20 15:24:55 2016 -0800 12.2 +++ b/src/share/classes/com/sun/tools/doclint/HtmlTag.java Thu Dec 22 16:21:25 2016 -0800 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -183,7 +183,8 @@ 12.11 } 12.12 }, 12.13 12.14 - SCRIPT(BlockType.OTHER, EndKind.REQUIRED), 12.15 + SCRIPT(BlockType.OTHER, EndKind.REQUIRED, 12.16 + attrs(AttrKind.OK, SRC)), 12.17 12.18 SMALL(BlockType.INLINE, EndKind.REQUIRED, 12.19 EnumSet.of(Flag.EXPECT_CONTENT)),
13.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Tue Dec 20 15:24:55 2016 -0800 13.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Dec 22 16:21:25 2016 -0800 13.3 @@ -1,5 +1,5 @@ 13.4 /* 13.5 - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 13.6 + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. 13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 * 13.9 * This code is free software; you can redistribute it and/or modify it 13.10 @@ -585,7 +585,7 @@ 13.11 /** 13.12 * Ident = IDENTIFIER 13.13 */ 13.14 - Name ident() { 13.15 + public Name ident() { 13.16 if (token.kind == IDENTIFIER) { 13.17 Name name = token.name(); 13.18 nextToken();
14.1 --- a/src/share/classes/com/sun/tools/javadoc/DocEnv.java Tue Dec 20 15:24:55 2016 -0800 14.2 +++ b/src/share/classes/com/sun/tools/javadoc/DocEnv.java Thu Dec 22 16:21:25 2016 -0800 14.3 @@ -1,5 +1,5 @@ 14.4 /* 14.5 - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 14.6 + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 14.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.8 * 14.9 * This code is free software; you can redistribute it and/or modify it 14.10 @@ -86,7 +86,7 @@ 14.11 JavadocEnter enter; 14.12 14.13 /** The name table. */ 14.14 - Names names; 14.15 + private final Names names; 14.16 14.17 /** The encoding name. */ 14.18 private String encoding; 14.19 @@ -109,6 +109,7 @@ 14.20 JavaFileManager fileManager; 14.21 Context context; 14.22 DocLint doclint; 14.23 + JavaScriptScanner javaScriptScanner; 14.24 14.25 WeakHashMap<JCTree, TreePath> treePaths = new WeakHashMap<JCTree, TreePath>(); 14.26 14.27 @@ -834,6 +835,15 @@ 14.28 doclint.init(t, doclintOpts.toArray(new String[doclintOpts.size()]), false); 14.29 } 14.30 14.31 + JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) { 14.32 + if (allowScriptInComments) { 14.33 + javaScriptScanner = null; 14.34 + } else { 14.35 + javaScriptScanner = new JavaScriptScanner(); 14.36 + } 14.37 + return javaScriptScanner; 14.38 + } 14.39 + 14.40 boolean showTagMessages() { 14.41 return (doclint == null); 14.42 }
15.1 --- a/src/share/classes/com/sun/tools/javadoc/DocImpl.java Tue Dec 20 15:24:55 2016 -0800 15.2 +++ b/src/share/classes/com/sun/tools/javadoc/DocImpl.java Thu Dec 22 16:21:25 2016 -0800 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -36,6 +36,7 @@ 15.11 15.12 import com.sun.javadoc.*; 15.13 import com.sun.source.util.TreePath; 15.14 +import com.sun.tools.doclets.internal.toolkit.util.FatalError; 15.15 import com.sun.tools.javac.tree.JCTree; 15.16 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; 15.17 import com.sun.tools.javac.util.Position; 15.18 @@ -127,6 +128,15 @@ 15.19 Comment comment() { 15.20 if (comment == null) { 15.21 String d = documentation(); 15.22 + if (env.javaScriptScanner != null) { 15.23 + env.javaScriptScanner.parse(d, new JavaScriptScanner.Reporter() { 15.24 + @Override 15.25 + public void report() { 15.26 + env.error(DocImpl.this, "javadoc.JavaScript_in_comment"); 15.27 + throw new FatalError(); 15.28 + } 15.29 + }); 15.30 + } 15.31 if (env.doclint != null 15.32 && treePath != null 15.33 && d.equals(getCommentText(treePath))) {
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavaScriptScanner.java Thu Dec 22 16:21:25 2016 -0800 16.3 @@ -0,0 +1,1103 @@ 16.4 +/* 16.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.7 + * 16.8 + * This code is free software; you can redistribute it and/or modify it 16.9 + * under the terms of the GNU General Public License version 2 only, as 16.10 + * published by the Free Software Foundation. Oracle designates this 16.11 + * particular file as subject to the "Classpath" exception as provided 16.12 + * by Oracle in the LICENSE file that accompanied this code. 16.13 + * 16.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 16.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16.17 + * version 2 for more details (a copy is included in the LICENSE file that 16.18 + * accompanied this code). 16.19 + * 16.20 + * You should have received a copy of the GNU General Public License version 16.21 + * 2 along with this work; if not, write to the Free Software Foundation, 16.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 16.23 + * 16.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 16.25 + * or visit www.oracle.com if you need additional information or have any 16.26 + * questions. 16.27 + */ 16.28 + 16.29 +package com.sun.tools.javadoc; 16.30 + 16.31 +import java.util.Arrays; 16.32 +import java.util.HashMap; 16.33 +import java.util.HashSet; 16.34 +import java.util.Locale; 16.35 +import java.util.Map; 16.36 +import java.util.Set; 16.37 + 16.38 +import com.sun.tools.javadoc.JavaScriptScanner.TagParser.Kind; 16.39 + 16.40 +import static com.sun.tools.javac.util.LayoutCharacters.EOI; 16.41 + 16.42 +/** 16.43 + * Parser to detect use of JavaScript in documentation comments. 16.44 + */ 16.45 +@Deprecated 16.46 +public class JavaScriptScanner { 16.47 + public static interface Reporter { 16.48 + void report(); 16.49 + } 16.50 + 16.51 + static class ParseException extends Exception { 16.52 + private static final long serialVersionUID = 0; 16.53 + ParseException(String key) { 16.54 + super(key); 16.55 + } 16.56 + } 16.57 + 16.58 + private Reporter reporter; 16.59 + 16.60 + /** The input buffer, index of most recent character read, 16.61 + * index of one past last character in buffer. 16.62 + */ 16.63 + protected char[] buf; 16.64 + protected int bp; 16.65 + protected int buflen; 16.66 + 16.67 + /** The current character. 16.68 + */ 16.69 + protected char ch; 16.70 + 16.71 + private boolean newline = true; 16.72 + 16.73 + Map<String, TagParser> tagParsers; 16.74 + Set<String> eventAttrs; 16.75 + Set<String> uriAttrs; 16.76 + 16.77 + public JavaScriptScanner() { 16.78 + initTagParsers(); 16.79 + initEventAttrs(); 16.80 + initURIAttrs(); 16.81 + } 16.82 + 16.83 + public void parse(String comment, Reporter r) { 16.84 + reporter = r; 16.85 + String c = comment; 16.86 + buf = new char[c.length() + 1]; 16.87 + c.getChars(0, c.length(), buf, 0); 16.88 + buf[buf.length - 1] = EOI; 16.89 + buflen = buf.length - 1; 16.90 + bp = -1; 16.91 + newline = true; 16.92 + nextChar(); 16.93 + 16.94 + blockContent(); 16.95 + blockTags(); 16.96 + } 16.97 + 16.98 + private void checkHtmlTag(String tag) { 16.99 + if (tag.equalsIgnoreCase("script")) { 16.100 + reporter.report(); 16.101 + } 16.102 + } 16.103 + 16.104 + private void checkHtmlAttr(String name, String value) { 16.105 + String n = name.toLowerCase(Locale.ENGLISH); 16.106 + if (eventAttrs.contains(n) 16.107 + || uriAttrs.contains(n) 16.108 + && value != null && value.toLowerCase(Locale.ENGLISH).trim().startsWith("javascript:")) { 16.109 + reporter.report(); 16.110 + } 16.111 + } 16.112 + 16.113 + void nextChar() { 16.114 + ch = buf[bp < buflen ? ++bp : buflen]; 16.115 + switch (ch) { 16.116 + case '\f': case '\n': case '\r': 16.117 + newline = true; 16.118 + } 16.119 + } 16.120 + 16.121 + /** 16.122 + * Read block content, consisting of text, html and inline tags. 16.123 + * Terminated by the end of input, or the beginning of the next block tag: 16.124 + * i.e. @ as the first non-whitespace character on a line. 16.125 + */ 16.126 + @SuppressWarnings("fallthrough") 16.127 + protected void blockContent() { 16.128 + 16.129 + loop: 16.130 + while (bp < buflen) { 16.131 + switch (ch) { 16.132 + case '\n': case '\r': case '\f': 16.133 + newline = true; 16.134 + // fallthrough 16.135 + 16.136 + case ' ': case '\t': 16.137 + nextChar(); 16.138 + break; 16.139 + 16.140 + case '&': 16.141 + entity(null); 16.142 + break; 16.143 + 16.144 + case '<': 16.145 + html(); 16.146 + break; 16.147 + 16.148 + case '>': 16.149 + newline = false; 16.150 + nextChar(); 16.151 + break; 16.152 + 16.153 + case '{': 16.154 + inlineTag(null); 16.155 + break; 16.156 + 16.157 + case '@': 16.158 + if (newline) { 16.159 + break loop; 16.160 + } 16.161 + // fallthrough 16.162 + 16.163 + default: 16.164 + newline = false; 16.165 + nextChar(); 16.166 + } 16.167 + } 16.168 + } 16.169 + 16.170 + /** 16.171 + * Read a series of block tags, including their content. 16.172 + * Standard tags parse their content appropriately. 16.173 + * Non-standard tags are represented by {@link UnknownBlockTag}. 16.174 + */ 16.175 + protected void blockTags() { 16.176 + while (ch == '@') 16.177 + blockTag(); 16.178 + } 16.179 + 16.180 + /** 16.181 + * Read a single block tag, including its content. 16.182 + * Standard tags parse their content appropriately. 16.183 + * Non-standard tags are represented by {@link UnknownBlockTag}. 16.184 + */ 16.185 + protected void blockTag() { 16.186 + int p = bp; 16.187 + try { 16.188 + nextChar(); 16.189 + if (isIdentifierStart(ch)) { 16.190 + String name = readTagName(); 16.191 + TagParser tp = tagParsers.get(name); 16.192 + if (tp == null) { 16.193 + blockContent(); 16.194 + } else { 16.195 + switch (tp.getKind()) { 16.196 + case BLOCK: 16.197 + tp.parse(p); 16.198 + return; 16.199 + case INLINE: 16.200 + return; 16.201 + } 16.202 + } 16.203 + } 16.204 + blockContent(); 16.205 + } catch (ParseException e) { 16.206 + blockContent(); 16.207 + } 16.208 + } 16.209 + 16.210 + protected void inlineTag(Void list) { 16.211 + newline = false; 16.212 + nextChar(); 16.213 + if (ch == '@') { 16.214 + inlineTag(); 16.215 + } 16.216 + } 16.217 + 16.218 + /** 16.219 + * Read a single inline tag, including its content. 16.220 + * Standard tags parse their content appropriately. 16.221 + * Non-standard tags are represented by {@link UnknownBlockTag}. 16.222 + * Malformed tags may be returned as {@link Erroneous}. 16.223 + */ 16.224 + protected void inlineTag() { 16.225 + int p = bp - 1; 16.226 + try { 16.227 + nextChar(); 16.228 + if (isIdentifierStart(ch)) { 16.229 + String name = readTagName(); 16.230 + TagParser tp = tagParsers.get(name); 16.231 + 16.232 + if (tp == null) { 16.233 + skipWhitespace(); 16.234 + inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); 16.235 + nextChar(); 16.236 + } else { 16.237 + skipWhitespace(); 16.238 + if (tp.getKind() == TagParser.Kind.INLINE) { 16.239 + tp.parse(p); 16.240 + } else { // handle block tags (ex: @see) in inline content 16.241 + inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip content 16.242 + nextChar(); 16.243 + } 16.244 + } 16.245 + } 16.246 + } catch (ParseException e) { 16.247 + } 16.248 + } 16.249 + 16.250 + private static enum WhitespaceRetentionPolicy { 16.251 + RETAIN_ALL, 16.252 + REMOVE_FIRST_SPACE, 16.253 + REMOVE_ALL 16.254 + } 16.255 + 16.256 + /** 16.257 + * Read plain text content of an inline tag. 16.258 + * Matching pairs of { } are skipped; the text is terminated by the first 16.259 + * unmatched }. It is an error if the beginning of the next tag is detected. 16.260 + */ 16.261 + private void inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException { 16.262 + switch (whitespacePolicy) { 16.263 + case REMOVE_ALL: 16.264 + skipWhitespace(); 16.265 + break; 16.266 + case REMOVE_FIRST_SPACE: 16.267 + if (ch == ' ') 16.268 + nextChar(); 16.269 + break; 16.270 + case RETAIN_ALL: 16.271 + default: 16.272 + // do nothing 16.273 + break; 16.274 + 16.275 + } 16.276 + int pos = bp; 16.277 + int depth = 1; 16.278 + 16.279 + loop: 16.280 + while (bp < buflen) { 16.281 + switch (ch) { 16.282 + case '\n': case '\r': case '\f': 16.283 + newline = true; 16.284 + break; 16.285 + 16.286 + case ' ': case '\t': 16.287 + break; 16.288 + 16.289 + case '{': 16.290 + newline = false; 16.291 + depth++; 16.292 + break; 16.293 + 16.294 + case '}': 16.295 + if (--depth == 0) { 16.296 + return; 16.297 + } 16.298 + newline = false; 16.299 + break; 16.300 + 16.301 + case '@': 16.302 + if (newline) 16.303 + break loop; 16.304 + newline = false; 16.305 + break; 16.306 + 16.307 + default: 16.308 + newline = false; 16.309 + break; 16.310 + } 16.311 + nextChar(); 16.312 + } 16.313 + throw new ParseException("dc.unterminated.inline.tag"); 16.314 + } 16.315 + 16.316 + /** 16.317 + * Read Java class name, possibly followed by member 16.318 + * Matching pairs of {@literal < >} are skipped. The text is terminated by the first 16.319 + * unmatched }. It is an error if the beginning of the next tag is detected. 16.320 + */ 16.321 + // TODO: boolean allowMember should be enum FORBID, ALLOW, REQUIRE 16.322 + // TODO: improve quality of parse to forbid bad constructions. 16.323 + // TODO: update to use ReferenceParser 16.324 + @SuppressWarnings("fallthrough") 16.325 + protected void reference(boolean allowMember) throws ParseException { 16.326 + int pos = bp; 16.327 + int depth = 0; 16.328 + 16.329 + // scan to find the end of the signature, by looking for the first 16.330 + // whitespace not enclosed in () or <>, or the end of the tag 16.331 + loop: 16.332 + while (bp < buflen) { 16.333 + switch (ch) { 16.334 + case '\n': case '\r': case '\f': 16.335 + newline = true; 16.336 + // fallthrough 16.337 + 16.338 + case ' ': case '\t': 16.339 + if (depth == 0) 16.340 + break loop; 16.341 + break; 16.342 + 16.343 + case '(': 16.344 + case '<': 16.345 + newline = false; 16.346 + depth++; 16.347 + break; 16.348 + 16.349 + case ')': 16.350 + case '>': 16.351 + newline = false; 16.352 + --depth; 16.353 + break; 16.354 + 16.355 + case '}': 16.356 + if (bp == pos) 16.357 + return; 16.358 + newline = false; 16.359 + break loop; 16.360 + 16.361 + case '@': 16.362 + if (newline) 16.363 + break loop; 16.364 + // fallthrough 16.365 + 16.366 + default: 16.367 + newline = false; 16.368 + 16.369 + } 16.370 + nextChar(); 16.371 + } 16.372 + 16.373 + if (depth != 0) 16.374 + throw new ParseException("dc.unterminated.signature"); 16.375 + } 16.376 + 16.377 + /** 16.378 + * Read Java identifier 16.379 + * Matching pairs of { } are skipped; the text is terminated by the first 16.380 + * unmatched }. It is an error if the beginning of the next tag is detected. 16.381 + */ 16.382 + @SuppressWarnings("fallthrough") 16.383 + protected void identifier() throws ParseException { 16.384 + skipWhitespace(); 16.385 + int pos = bp; 16.386 + 16.387 + if (isJavaIdentifierStart(ch)) { 16.388 + readJavaIdentifier(); 16.389 + return; 16.390 + } 16.391 + 16.392 + throw new ParseException("dc.identifier.expected"); 16.393 + } 16.394 + 16.395 + /** 16.396 + * Read a quoted string. 16.397 + * It is an error if the beginning of the next tag is detected. 16.398 + */ 16.399 + @SuppressWarnings("fallthrough") 16.400 + protected void quotedString() { 16.401 + int pos = bp; 16.402 + nextChar(); 16.403 + 16.404 + loop: 16.405 + while (bp < buflen) { 16.406 + switch (ch) { 16.407 + case '\n': case '\r': case '\f': 16.408 + newline = true; 16.409 + break; 16.410 + 16.411 + case ' ': case '\t': 16.412 + break; 16.413 + 16.414 + case '"': 16.415 + nextChar(); 16.416 + // trim trailing white-space? 16.417 + return; 16.418 + 16.419 + case '@': 16.420 + if (newline) 16.421 + break loop; 16.422 + 16.423 + } 16.424 + nextChar(); 16.425 + } 16.426 + } 16.427 + 16.428 + /** 16.429 + * Read a term ie. one word. 16.430 + * It is an error if the beginning of the next tag is detected. 16.431 + */ 16.432 + @SuppressWarnings("fallthrough") 16.433 + protected void inlineWord() { 16.434 + int pos = bp; 16.435 + int depth = 0; 16.436 + loop: 16.437 + while (bp < buflen) { 16.438 + switch (ch) { 16.439 + case '\n': 16.440 + newline = true; 16.441 + // fallthrough 16.442 + 16.443 + case '\r': case '\f': case ' ': case '\t': 16.444 + return; 16.445 + 16.446 + case '@': 16.447 + if (newline) 16.448 + break loop; 16.449 + 16.450 + case '{': 16.451 + depth++; 16.452 + break; 16.453 + 16.454 + case '}': 16.455 + if (depth == 0 || --depth == 0) 16.456 + return; 16.457 + break; 16.458 + } 16.459 + newline = false; 16.460 + nextChar(); 16.461 + } 16.462 + } 16.463 + 16.464 + /** 16.465 + * Read general text content of an inline tag, including HTML entities and elements. 16.466 + * Matching pairs of { } are skipped; the text is terminated by the first 16.467 + * unmatched }. It is an error if the beginning of the next tag is detected. 16.468 + */ 16.469 + @SuppressWarnings("fallthrough") 16.470 + private void inlineContent() { 16.471 + 16.472 + skipWhitespace(); 16.473 + int pos = bp; 16.474 + int depth = 1; 16.475 + 16.476 + loop: 16.477 + while (bp < buflen) { 16.478 + 16.479 + switch (ch) { 16.480 + case '\n': case '\r': case '\f': 16.481 + newline = true; 16.482 + // fall through 16.483 + 16.484 + case ' ': case '\t': 16.485 + nextChar(); 16.486 + break; 16.487 + 16.488 + case '&': 16.489 + entity(null); 16.490 + break; 16.491 + 16.492 + case '<': 16.493 + newline = false; 16.494 + html(); 16.495 + break; 16.496 + 16.497 + case '{': 16.498 + newline = false; 16.499 + depth++; 16.500 + nextChar(); 16.501 + break; 16.502 + 16.503 + case '}': 16.504 + newline = false; 16.505 + if (--depth == 0) { 16.506 + nextChar(); 16.507 + return; 16.508 + } 16.509 + nextChar(); 16.510 + break; 16.511 + 16.512 + case '@': 16.513 + if (newline) 16.514 + break loop; 16.515 + // fallthrough 16.516 + 16.517 + default: 16.518 + nextChar(); 16.519 + break; 16.520 + } 16.521 + } 16.522 + 16.523 + } 16.524 + 16.525 + protected void entity(Void list) { 16.526 + newline = false; 16.527 + entity(); 16.528 + } 16.529 + 16.530 + /** 16.531 + * Read an HTML entity. 16.532 + * {@literal &identifier; } or {@literal &#digits; } or {@literal &#xhex-digits; } 16.533 + */ 16.534 + protected void entity() { 16.535 + nextChar(); 16.536 + String name = null; 16.537 + if (ch == '#') { 16.538 + int namep = bp; 16.539 + nextChar(); 16.540 + if (isDecimalDigit(ch)) { 16.541 + nextChar(); 16.542 + while (isDecimalDigit(ch)) 16.543 + nextChar(); 16.544 + name = new String(buf, namep, bp - namep); 16.545 + } else if (ch == 'x' || ch == 'X') { 16.546 + nextChar(); 16.547 + if (isHexDigit(ch)) { 16.548 + nextChar(); 16.549 + while (isHexDigit(ch)) 16.550 + nextChar(); 16.551 + name = new String(buf, namep, bp - namep); 16.552 + } 16.553 + } 16.554 + } else if (isIdentifierStart(ch)) { 16.555 + name = readIdentifier(); 16.556 + } 16.557 + 16.558 + if (name != null) { 16.559 + if (ch != ';') 16.560 + return; 16.561 + nextChar(); 16.562 + } 16.563 + } 16.564 + 16.565 + /** 16.566 + * Read the start or end of an HTML tag, or an HTML comment 16.567 + * {@literal <identifier attrs> } or {@literal </identifier> } 16.568 + */ 16.569 + protected void html() { 16.570 + int p = bp; 16.571 + nextChar(); 16.572 + if (isIdentifierStart(ch)) { 16.573 + String name = readIdentifier(); 16.574 + checkHtmlTag(name); 16.575 + htmlAttrs(); 16.576 + if (ch == '/') { 16.577 + nextChar(); 16.578 + } 16.579 + if (ch == '>') { 16.580 + nextChar(); 16.581 + return; 16.582 + } 16.583 + } else if (ch == '/') { 16.584 + nextChar(); 16.585 + if (isIdentifierStart(ch)) { 16.586 + readIdentifier(); 16.587 + skipWhitespace(); 16.588 + if (ch == '>') { 16.589 + nextChar(); 16.590 + return; 16.591 + } 16.592 + } 16.593 + } else if (ch == '!') { 16.594 + nextChar(); 16.595 + if (ch == '-') { 16.596 + nextChar(); 16.597 + if (ch == '-') { 16.598 + nextChar(); 16.599 + while (bp < buflen) { 16.600 + int dash = 0; 16.601 + while (ch == '-') { 16.602 + dash++; 16.603 + nextChar(); 16.604 + } 16.605 + // Strictly speaking, a comment should not contain "--" 16.606 + // so dash > 2 is an error, dash == 2 implies ch == '>' 16.607 + // See http://www.w3.org/TR/html-markup/syntax.html#syntax-comments 16.608 + // for more details. 16.609 + if (dash >= 2 && ch == '>') { 16.610 + nextChar(); 16.611 + return; 16.612 + } 16.613 + 16.614 + nextChar(); 16.615 + } 16.616 + } 16.617 + } 16.618 + } 16.619 + 16.620 + bp = p + 1; 16.621 + ch = buf[bp]; 16.622 + } 16.623 + 16.624 + /** 16.625 + * Read a series of HTML attributes, terminated by {@literal > }. 16.626 + * Each attribute is of the form {@literal identifier[=value] }. 16.627 + * "value" may be unquoted, single-quoted, or double-quoted. 16.628 + */ 16.629 + protected void htmlAttrs() { 16.630 + skipWhitespace(); 16.631 + 16.632 + loop: 16.633 + while (isIdentifierStart(ch)) { 16.634 + int namePos = bp; 16.635 + String name = readAttributeName(); 16.636 + skipWhitespace(); 16.637 + StringBuilder value = new StringBuilder(); 16.638 + if (ch == '=') { 16.639 + nextChar(); 16.640 + skipWhitespace(); 16.641 + if (ch == '\'' || ch == '"') { 16.642 + char quote = ch; 16.643 + nextChar(); 16.644 + while (bp < buflen && ch != quote) { 16.645 + if (newline && ch == '@') { 16.646 + // No point trying to read more. 16.647 + // In fact, all attrs get discarded by the caller 16.648 + // and superseded by a malformed.html node because 16.649 + // the html tag itself is not terminated correctly. 16.650 + break loop; 16.651 + } 16.652 + value.append(ch); 16.653 + nextChar(); 16.654 + } 16.655 + nextChar(); 16.656 + } else { 16.657 + while (bp < buflen && !isUnquotedAttrValueTerminator(ch)) { 16.658 + value.append(ch); 16.659 + nextChar(); 16.660 + } 16.661 + } 16.662 + skipWhitespace(); 16.663 + } 16.664 + checkHtmlAttr(name, value.toString()); 16.665 + } 16.666 + } 16.667 + 16.668 + protected void attrValueChar(Void list) { 16.669 + switch (ch) { 16.670 + case '&': 16.671 + entity(list); 16.672 + break; 16.673 + 16.674 + case '{': 16.675 + inlineTag(list); 16.676 + break; 16.677 + 16.678 + default: 16.679 + nextChar(); 16.680 + } 16.681 + } 16.682 + 16.683 + protected boolean isIdentifierStart(char ch) { 16.684 + return Character.isUnicodeIdentifierStart(ch); 16.685 + } 16.686 + 16.687 + protected String readIdentifier() { 16.688 + int start = bp; 16.689 + nextChar(); 16.690 + while (bp < buflen && Character.isUnicodeIdentifierPart(ch)) 16.691 + nextChar(); 16.692 + return new String(buf, start, bp - start); 16.693 + } 16.694 + 16.695 + protected String readAttributeName() { 16.696 + int start = bp; 16.697 + nextChar(); 16.698 + while (bp < buflen && (Character.isUnicodeIdentifierPart(ch) || ch == '-')) 16.699 + nextChar(); 16.700 + return new String(buf, start, bp - start); 16.701 + } 16.702 + 16.703 + protected String readTagName() { 16.704 + int start = bp; 16.705 + nextChar(); 16.706 + while (bp < buflen 16.707 + && (Character.isUnicodeIdentifierPart(ch) || ch == '.' 16.708 + || ch == '-' || ch == ':')) { 16.709 + nextChar(); 16.710 + } 16.711 + return new String(buf, start, bp - start); 16.712 + } 16.713 + 16.714 + protected boolean isJavaIdentifierStart(char ch) { 16.715 + return Character.isJavaIdentifierStart(ch); 16.716 + } 16.717 + 16.718 + protected String readJavaIdentifier() { 16.719 + int start = bp; 16.720 + nextChar(); 16.721 + while (bp < buflen && Character.isJavaIdentifierPart(ch)) 16.722 + nextChar(); 16.723 + return new String(buf, start, bp - start); 16.724 + } 16.725 + 16.726 + protected boolean isDecimalDigit(char ch) { 16.727 + return ('0' <= ch && ch <= '9'); 16.728 + } 16.729 + 16.730 + protected boolean isHexDigit(char ch) { 16.731 + return ('0' <= ch && ch <= '9') 16.732 + || ('a' <= ch && ch <= 'f') 16.733 + || ('A' <= ch && ch <= 'F'); 16.734 + } 16.735 + 16.736 + protected boolean isUnquotedAttrValueTerminator(char ch) { 16.737 + switch (ch) { 16.738 + case '\f': case '\n': case '\r': case '\t': 16.739 + case ' ': 16.740 + case '"': case '\'': case '`': 16.741 + case '=': case '<': case '>': 16.742 + return true; 16.743 + default: 16.744 + return false; 16.745 + } 16.746 + } 16.747 + 16.748 + protected boolean isWhitespace(char ch) { 16.749 + return Character.isWhitespace(ch); 16.750 + } 16.751 + 16.752 + protected void skipWhitespace() { 16.753 + while (isWhitespace(ch)) { 16.754 + nextChar(); 16.755 + } 16.756 + } 16.757 + 16.758 + /** 16.759 + * @param start position of first character of string 16.760 + * @param end position of character beyond last character to be included 16.761 + */ 16.762 + String newString(int start, int end) { 16.763 + return new String(buf, start, end - start); 16.764 + } 16.765 + 16.766 + static abstract class TagParser { 16.767 + enum Kind { INLINE, BLOCK } 16.768 + 16.769 + final Kind kind; 16.770 + final String name; 16.771 + 16.772 + 16.773 + TagParser(Kind k, String tk) { 16.774 + kind = k; 16.775 + name = tk; 16.776 + } 16.777 + 16.778 + TagParser(Kind k, String tk, boolean retainWhiteSpace) { 16.779 + this(k, tk); 16.780 + } 16.781 + 16.782 + Kind getKind() { 16.783 + return kind; 16.784 + } 16.785 + 16.786 + String getName() { 16.787 + return name; 16.788 + } 16.789 + 16.790 + abstract void parse(int pos) throws ParseException; 16.791 + } 16.792 + 16.793 + /** 16.794 + * @see <a href="http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javadoc.html#javadoctags">Javadoc Tags</a> 16.795 + */ 16.796 + @SuppressWarnings("deprecation") 16.797 + private void initTagParsers() { 16.798 + TagParser[] parsers = { 16.799 + // @author name-text 16.800 + new TagParser(Kind.BLOCK, "author") { 16.801 + @Override 16.802 + public void parse(int pos) { 16.803 + blockContent(); 16.804 + } 16.805 + }, 16.806 + 16.807 + // {@code text} 16.808 + new TagParser(Kind.INLINE, "code", true) { 16.809 + @Override 16.810 + public void parse(int pos) throws ParseException { 16.811 + inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE); 16.812 + nextChar(); 16.813 + } 16.814 + }, 16.815 + 16.816 + // @deprecated deprecated-text 16.817 + new TagParser(Kind.BLOCK, "deprecated") { 16.818 + @Override 16.819 + public void parse(int pos) { 16.820 + blockContent(); 16.821 + } 16.822 + }, 16.823 + 16.824 + // {@docRoot} 16.825 + new TagParser(Kind.INLINE, "docRoot") { 16.826 + @Override 16.827 + public void parse(int pos) throws ParseException { 16.828 + if (ch == '}') { 16.829 + nextChar(); 16.830 + return; 16.831 + } 16.832 + inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content 16.833 + nextChar(); 16.834 + throw new ParseException("dc.unexpected.content"); 16.835 + } 16.836 + }, 16.837 + 16.838 + // @exception class-name description 16.839 + new TagParser(Kind.BLOCK, "exception") { 16.840 + @Override 16.841 + public void parse(int pos) throws ParseException { 16.842 + skipWhitespace(); 16.843 + reference(false); 16.844 + blockContent(); 16.845 + } 16.846 + }, 16.847 + 16.848 + // @hidden hidden-text 16.849 + new TagParser(Kind.BLOCK, "hidden") { 16.850 + @Override 16.851 + public void parse(int pos) { 16.852 + blockContent(); 16.853 + } 16.854 + }, 16.855 + 16.856 + // @index search-term options-description 16.857 + new TagParser(Kind.INLINE, "index") { 16.858 + @Override 16.859 + public void parse(int pos) throws ParseException { 16.860 + skipWhitespace(); 16.861 + if (ch == '}') { 16.862 + throw new ParseException("dc.no.content"); 16.863 + } 16.864 + if (ch == '"') quotedString(); else inlineWord(); 16.865 + skipWhitespace(); 16.866 + if (ch != '}') { 16.867 + inlineContent(); 16.868 + } else { 16.869 + nextChar(); 16.870 + } 16.871 + } 16.872 + }, 16.873 + 16.874 + // {@inheritDoc} 16.875 + new TagParser(Kind.INLINE, "inheritDoc") { 16.876 + @Override 16.877 + public void parse(int pos) throws ParseException { 16.878 + if (ch == '}') { 16.879 + nextChar(); 16.880 + return; 16.881 + } 16.882 + inlineText(WhitespaceRetentionPolicy.REMOVE_ALL); // skip unexpected content 16.883 + nextChar(); 16.884 + throw new ParseException("dc.unexpected.content"); 16.885 + } 16.886 + }, 16.887 + 16.888 + // {@link package.class#member label} 16.889 + new TagParser(Kind.INLINE, "link") { 16.890 + @Override 16.891 + public void parse(int pos) throws ParseException { 16.892 + reference(true); 16.893 + inlineContent(); 16.894 + } 16.895 + }, 16.896 + 16.897 + // {@linkplain package.class#member label} 16.898 + new TagParser(Kind.INLINE, "linkplain") { 16.899 + @Override 16.900 + public void parse(int pos) throws ParseException { 16.901 + reference(true); 16.902 + inlineContent(); 16.903 + } 16.904 + }, 16.905 + 16.906 + // {@literal text} 16.907 + new TagParser(Kind.INLINE, "literal", true) { 16.908 + @Override 16.909 + public void parse(int pos) throws ParseException { 16.910 + inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE); 16.911 + nextChar(); 16.912 + } 16.913 + }, 16.914 + 16.915 + // @param parameter-name description 16.916 + new TagParser(Kind.BLOCK, "param") { 16.917 + @Override 16.918 + public void parse(int pos) throws ParseException { 16.919 + skipWhitespace(); 16.920 + 16.921 + boolean typaram = false; 16.922 + if (ch == '<') { 16.923 + typaram = true; 16.924 + nextChar(); 16.925 + } 16.926 + 16.927 + identifier(); 16.928 + 16.929 + if (typaram) { 16.930 + if (ch != '>') 16.931 + throw new ParseException("dc.gt.expected"); 16.932 + nextChar(); 16.933 + } 16.934 + 16.935 + skipWhitespace(); 16.936 + blockContent(); 16.937 + } 16.938 + }, 16.939 + 16.940 + // @return description 16.941 + new TagParser(Kind.BLOCK, "return") { 16.942 + @Override 16.943 + public void parse(int pos) { 16.944 + blockContent(); 16.945 + } 16.946 + }, 16.947 + 16.948 + // @see reference | quoted-string | HTML 16.949 + new TagParser(Kind.BLOCK, "see") { 16.950 + @Override 16.951 + public void parse(int pos) throws ParseException { 16.952 + skipWhitespace(); 16.953 + switch (ch) { 16.954 + case '"': 16.955 + quotedString(); 16.956 + skipWhitespace(); 16.957 + if (ch == '@' 16.958 + || ch == EOI && bp == buf.length - 1) { 16.959 + return; 16.960 + } 16.961 + break; 16.962 + 16.963 + case '<': 16.964 + blockContent(); 16.965 + return; 16.966 + 16.967 + case '@': 16.968 + if (newline) 16.969 + throw new ParseException("dc.no.content"); 16.970 + break; 16.971 + 16.972 + case EOI: 16.973 + if (bp == buf.length - 1) 16.974 + throw new ParseException("dc.no.content"); 16.975 + break; 16.976 + 16.977 + default: 16.978 + if (isJavaIdentifierStart(ch) || ch == '#') { 16.979 + reference(true); 16.980 + blockContent(); 16.981 + } 16.982 + } 16.983 + throw new ParseException("dc.unexpected.content"); 16.984 + } 16.985 + }, 16.986 + 16.987 + // @serialData data-description 16.988 + new TagParser(Kind.BLOCK, "@serialData") { 16.989 + @Override 16.990 + public void parse(int pos) { 16.991 + blockContent(); 16.992 + } 16.993 + }, 16.994 + 16.995 + // @serialField field-name field-type description 16.996 + new TagParser(Kind.BLOCK, "serialField") { 16.997 + @Override 16.998 + public void parse(int pos) throws ParseException { 16.999 + skipWhitespace(); 16.1000 + identifier(); 16.1001 + skipWhitespace(); 16.1002 + reference(false); 16.1003 + if (isWhitespace(ch)) { 16.1004 + skipWhitespace(); 16.1005 + blockContent(); 16.1006 + } 16.1007 + } 16.1008 + }, 16.1009 + 16.1010 + // @serial field-description | include | exclude 16.1011 + new TagParser(Kind.BLOCK, "serial") { 16.1012 + @Override 16.1013 + public void parse(int pos) { 16.1014 + blockContent(); 16.1015 + } 16.1016 + }, 16.1017 + 16.1018 + // @since since-text 16.1019 + new TagParser(Kind.BLOCK, "since") { 16.1020 + @Override 16.1021 + public void parse(int pos) { 16.1022 + blockContent(); 16.1023 + } 16.1024 + }, 16.1025 + 16.1026 + // @throws class-name description 16.1027 + new TagParser(Kind.BLOCK, "throws") { 16.1028 + @Override 16.1029 + public void parse(int pos) throws ParseException { 16.1030 + skipWhitespace(); 16.1031 + reference(false); 16.1032 + blockContent(); 16.1033 + } 16.1034 + }, 16.1035 + 16.1036 + // {@value package.class#field} 16.1037 + new TagParser(Kind.INLINE, "value") { 16.1038 + @Override 16.1039 + public void parse(int pos) throws ParseException { 16.1040 + reference(true); 16.1041 + skipWhitespace(); 16.1042 + if (ch == '}') { 16.1043 + nextChar(); 16.1044 + return; 16.1045 + } 16.1046 + nextChar(); 16.1047 + throw new ParseException("dc.unexpected.content"); 16.1048 + } 16.1049 + }, 16.1050 + 16.1051 + // @version version-text 16.1052 + new TagParser(Kind.BLOCK, "version") { 16.1053 + @Override 16.1054 + public void parse(int pos) { 16.1055 + blockContent(); 16.1056 + } 16.1057 + }, 16.1058 + }; 16.1059 + 16.1060 + tagParsers = new HashMap<>(); 16.1061 + for (TagParser p: parsers) 16.1062 + tagParsers.put(p.getName(), p); 16.1063 + 16.1064 + } 16.1065 + 16.1066 + private void initEventAttrs() { 16.1067 + eventAttrs = new HashSet<>(Arrays.asList( 16.1068 + // See https://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.event-handler 16.1069 + "onabort", "onblur", "oncanplay", "oncanplaythrough", 16.1070 + "onchange", "onclick", "oncontextmenu", "ondblclick", 16.1071 + "ondrag", "ondragend", "ondragenter", "ondragleave", 16.1072 + "ondragover", "ondragstart", "ondrop", "ondurationchange", 16.1073 + "onemptied", "onended", "onerror", "onfocus", "oninput", 16.1074 + "oninvalid", "onkeydown", "onkeypress", "onkeyup", 16.1075 + "onload", "onloadeddata", "onloadedmetadata", "onloadstart", 16.1076 + "onmousedown", "onmousemove", "onmouseout", "onmouseover", 16.1077 + "onmouseup", "onmousewheel", "onpause", "onplay", 16.1078 + "onplaying", "onprogress", "onratechange", "onreadystatechange", 16.1079 + "onreset", "onscroll", "onseeked", "onseeking", 16.1080 + "onselect", "onshow", "onstalled", "onsubmit", "onsuspend", 16.1081 + "ontimeupdate", "onvolumechange", "onwaiting", 16.1082 + 16.1083 + // See https://www.w3.org/TR/html4/sgml/dtd.html 16.1084 + // Most of the attributes that take a %Script are also defined as event handlers 16.1085 + // in HTML 5. The one exception is onunload. 16.1086 + // "onchange", "onclick", "ondblclick", "onfocus", 16.1087 + // "onkeydown", "onkeypress", "onkeyup", "onload", 16.1088 + // "onmousedown", "onmousemove", "onmouseout", "onmouseover", 16.1089 + // "onmouseup", "onreset", "onselect", "onsubmit", 16.1090 + "onunload" 16.1091 + )); 16.1092 + } 16.1093 + 16.1094 + private void initURIAttrs() { 16.1095 + uriAttrs = new HashSet<>(Arrays.asList( 16.1096 + // See https://www.w3.org/TR/html4/sgml/dtd.html 16.1097 + // https://www.w3.org/TR/html5/ 16.1098 + // These are all the attributes that take a %URI or a valid URL potentially surrounded 16.1099 + // by spaces 16.1100 + "action", "cite", "classid", "codebase", "data", 16.1101 + "datasrc", "for", "href", "longdesc", "profile", 16.1102 + "src", "usemap" 16.1103 + )); 16.1104 + } 16.1105 + 16.1106 +}
17.1 --- a/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java Tue Dec 20 15:24:55 2016 -0800 17.2 +++ b/src/share/classes/com/sun/tools/javadoc/RootDocImpl.java Thu Dec 22 16:21:25 2016 -0800 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -381,6 +381,10 @@ 17.11 env.initDoclint(opts, customTagNames); 17.12 } 17.13 17.14 + public JavaScriptScanner initJavaScriptScanner(boolean allowScriptInComments) { 17.15 + return env.initJavaScriptScanner(allowScriptInComments); 17.16 + } 17.17 + 17.18 public boolean isFunctionalInterface(AnnotationDesc annotationDesc) { 17.19 return annotationDesc.annotationType().qualifiedName().equals( 17.20 env.syms.functionalInterfaceType.toString()) && env.source.allowLambda();
18.1 --- a/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Tue Dec 20 15:24:55 2016 -0800 18.2 +++ b/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Thu Dec 22 16:21:25 2016 -0800 18.3 @@ -1,5 +1,5 @@ 18.4 # 18.5 -# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 18.6 +# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 18.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 # 18.9 # This code is free software; you can redistribute it and/or modify it 18.10 @@ -110,6 +110,8 @@ 18.11 javadoc.Body_missing_from_html_file=Body tag missing from HTML file 18.12 javadoc.End_body_missing_from_html_file=Close body tag missing from HTML file 18.13 javadoc.Multiple_package_comments=Multiple sources of package comments found for package "{0}" 18.14 +javadoc.JavaScript_in_comment=JavaScript found in documentation comment.\n\ 18.15 + Use --allow-script-in-comments to allow use of JavaScript. 18.16 javadoc.class_not_found=Class {0} not found. 18.17 javadoc.error=error 18.18 javadoc.warning=warning
19.1 --- a/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties Tue Dec 20 15:24:55 2016 -0800 19.2 +++ b/src/share/classes/com/sun/tools/javadoc/resources/javadoc_ja.properties Thu Dec 22 16:21:25 2016 -0800 19.3 @@ -1,5 +1,5 @@ 19.4 # 19.5 -# Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 19.6 +# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 19.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.8 # 19.9 # This code is free software; you can redistribute it and/or modify it 19.10 @@ -81,6 +81,7 @@ 19.11 javadoc.Body_missing_from_html_file=HTML\u306Bbody\u30BF\u30B0\u304C\u3042\u308A\u307E\u305B\u3093 19.12 javadoc.End_body_missing_from_html_file=HTML\u30D5\u30A1\u30A4\u30EB\u306Bbody\u306E\u9589\u3058\u30BF\u30B0\u304C\u3042\u308A\u307E\u305B\u3093 19.13 javadoc.Multiple_package_comments=\u30D1\u30C3\u30B1\u30FC\u30B8"{0}"\u306B\u8907\u6570\u306E\u30D1\u30C3\u30B1\u30FC\u30B8\u30FB\u30B3\u30E1\u30F3\u30C8\u306E\u30BD\u30FC\u30B9\u304C\u691C\u51FA\u3055\u308C\u307E\u3057\u305F 19.14 +javadoc.JavaScript_in_comment=\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u30FB\u30B3\u30E1\u30F3\u30C8\u306BJavaScript\u304C\u898B\u3064\u304B\u308A\u307E\u3057\u305F\u3002\n--allow-script-in-comments\u3092\u4F7F\u7528\u3057\u3066\u3001JavaScript\u306E\u4F7F\u7528\u3092\u8A31\u53EF\u3057\u3066\u304F\u3060\u3055\u3044\u3002 19.15 javadoc.class_not_found=\u30AF\u30E9\u30B9{0}\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002 19.16 javadoc.error=\u30A8\u30E9\u30FC 19.17 javadoc.warning=\u8B66\u544A
20.1 --- a/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties Tue Dec 20 15:24:55 2016 -0800 20.2 +++ b/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties Thu Dec 22 16:21:25 2016 -0800 20.3 @@ -1,5 +1,5 @@ 20.4 # 20.5 -# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 20.6 +# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 20.7 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 20.8 # 20.9 # This code is free software; you can redistribute it and/or modify it 20.10 @@ -81,6 +81,7 @@ 20.11 javadoc.Body_missing_from_html_file=HTML \u6587\u4EF6\u4E2D\u7F3A\u5C11\u4E3B\u4F53\u6807\u8BB0 20.12 javadoc.End_body_missing_from_html_file=HTML \u6587\u4EF6\u4E2D\u7F3A\u5C11\u4E3B\u4F53\u7ED3\u675F\u6807\u8BB0 20.13 javadoc.Multiple_package_comments=\u627E\u5230\u7A0B\u5E8F\u5305 "{0}" \u7684\u591A\u4E2A\u7A0B\u5E8F\u5305\u6CE8\u91CA\u6E90 20.14 +javadoc.JavaScript_in_comment=\u6587\u6863\u6CE8\u91CA\u4E2D\u53D1\u73B0 JavaScript\u3002\n\u4F7F\u7528 --allow-script-in-comments \u53EF\u5141\u8BB8\u4F7F\u7528 JavaScript\u3002 20.15 javadoc.class_not_found=\u627E\u4E0D\u5230\u7C7B{0}\u3002 20.16 javadoc.error=\u9519\u8BEF 20.17 javadoc.warning=\u8B66\u544A
21.1 --- a/test/tools/doclint/html/OtherTagsTest.out Tue Dec 20 15:24:55 2016 -0800 21.2 +++ b/test/tools/doclint/html/OtherTagsTest.out Thu Dec 22 16:21:25 2016 -0800 21.3 @@ -19,10 +19,7 @@ 21.4 OtherTagsTest.java:20: error: element not allowed in documentation comments: <noframes> 21.5 * <noframes> </noframes> 21.6 ^ 21.7 -OtherTagsTest.java:21: error: element not allowed in documentation comments: <script> 21.8 - * <script> </script> 21.9 - ^ 21.10 OtherTagsTest.java:22: error: element not allowed in documentation comments: <title> 21.11 * <title> </title> 21.12 ^ 21.13 -9 errors 21.14 +8 errors
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/test/tools/javadoc/TestScriptInComment.java Thu Dec 22 16:21:25 2016 -0800 22.3 @@ -0,0 +1,314 @@ 22.4 +/* 22.5 + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 + * 22.8 + * This code is free software; you can redistribute it and/or modify it 22.9 + * under the terms of the GNU General Public License version 2 only, as 22.10 + * published by the Free Software Foundation. Oracle designates this 22.11 + * particular file as subject to the "Classpath" exception as provided 22.12 + * by Oracle in the LICENSE file that accompanied this code. 22.13 + * 22.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 22.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.17 + * version 2 for more details (a copy is included in the LICENSE file that 22.18 + * accompanied this code). 22.19 + * 22.20 + * You should have received a copy of the GNU General Public License version 22.21 + * 2 along with this work; if not, write to the Free Software Foundation, 22.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.23 + * 22.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22.25 + * or visit www.oracle.com if you need additional information or have any 22.26 + * questions. 22.27 + */ 22.28 + 22.29 +/** 22.30 + * @test 22.31 + * @bug 8138725 22.32 + * @summary test --allow-script-in-comments 22.33 + * @run main TestScriptInComment 22.34 + */ 22.35 + 22.36 +import java.io.File; 22.37 +import java.io.FileWriter; 22.38 +import java.io.IOException; 22.39 +import java.io.PrintStream; 22.40 +import java.io.PrintWriter; 22.41 +import java.io.StringWriter; 22.42 +import java.util.ArrayList; 22.43 +import java.util.Arrays; 22.44 +import java.util.Collections; 22.45 +import java.util.List; 22.46 +import java.util.regex.Matcher; 22.47 +import java.util.regex.Pattern; 22.48 + 22.49 +/** 22.50 + * Combo-style test, exercising combinations of different HTML fragments that may contain 22.51 + * JavaScript, different places to place those fragments, and whether or not to allow the use 22.52 + * of JavaScript. 22.53 + */ 22.54 +public class TestScriptInComment { 22.55 + public static void main(String... args) throws Exception { 22.56 + new TestScriptInComment().run(); 22.57 + } 22.58 + 22.59 + /** 22.60 + * Representative samples of different fragments of HTML that may contain JavaScript. 22.61 + * To facilitate checking the output manually in a browser, the text "#ALERT" will be 22.62 + * replaced by a JavaScript call of "alert(msg)", using a message string that is specific 22.63 + * to the test case. 22.64 + */ 22.65 + enum Comment { 22.66 + LC("<script>#ALERT</script>", true), // script tag in Lower Case 22.67 + UC("<SCRIPT>#ALERT</script>", true), // script tag in Upper Case 22.68 + WS("< script >#ALERT</script>", false, "-Xdoclint:none"), // script tag with invalid white space 22.69 + SA("<script src=\"file\"> #ALERT </script>", true), // script tag with an attribute 22.70 + ON("<a onclick='#ALERT'>x</a>", true), // event handler attribute 22.71 + URI("<a href='javascript:#ALERT'>x</a>", true); // javadcript URI 22.72 + 22.73 + /** 22.74 + * Creates an HTML fragment to be injected into a template. 22.75 + * @param text the HTML fragment to put into a doc comment or option. 22.76 + * @param hasScript whether or not this fragment does contain legal JavaScript 22.77 + * @param opts any additional options to be specified when javadoc is run 22.78 + */ 22.79 + Comment(String text, boolean hasScript, String... opts) { 22.80 + this.text = text; 22.81 + this.hasScript = hasScript; 22.82 + this.opts = Arrays.asList(opts); 22.83 + } 22.84 + 22.85 + final String text; 22.86 + final boolean hasScript; 22.87 + final List<String> opts; 22.88 + }; 22.89 + 22.90 + /** 22.91 + * Representative samples of positions in which javadoc may find JavaScript. 22.92 + * Each template contains a series of strings, which are written to files or inferred as options. 22.93 + * The first source file implies a corresponding output file which should not be written 22.94 + * if the comment contains JavaScript and JavaScript is not allowed. 22.95 + */ 22.96 + enum Template { 22.97 + OVR("<html><body> overview #COMMENT </body></html>", "package p; public class C { }"), 22.98 + PKGINFO("#COMMENT package p;", "package p; public class C { }"), 22.99 + PKGHTML("<html><body>#COMMENT package p;</body></html>", "package p; public class C { }"), 22.100 + CLS("package p; #COMMENT public class C { }"), 22.101 + CON("package p; public class C { #COMMENT public C() { } }"), 22.102 + FLD("package p; public class C { #COMMENT public int f; }"), 22.103 + MTH("package p; public class C { #COMMENT public void m() { } }"), 22.104 + TOP("-top", "lorem #COMMENT ipsum", "package p; public class C { }"), 22.105 + HDR("-header", "lorem #COMMENT ipsum", "package p; public class C { }"), 22.106 + FTR("-footer", "lorem #COMMENT ipsum", "package p; public class C { }"), 22.107 + BTM("-bottom", "lorem #COMMENT ipsum", "package p; public class C { }"), 22.108 + DTTL("-doctitle", "lorem #COMMENT ipsum", "package p; public class C { }"), 22.109 + PHDR("-packagesheader", "lorem #COMMENT ipsum", "package p; public class C { }"); 22.110 + 22.111 + Template(String... args) { 22.112 + opts = new ArrayList<String>(); 22.113 + sources = new ArrayList<String>(); 22.114 + int i = 0; 22.115 + while (args[i].startsWith("-")) { 22.116 + // all options being tested have a single argument that follow the option 22.117 + opts.add(args[i++]); 22.118 + opts.add(args[i++]); 22.119 + } 22.120 + while(i < args.length) { 22.121 + sources.add(args[i++]); 22.122 + } 22.123 + } 22.124 + 22.125 + // groups: 1 <html> or not; 2: package name; 3: class name 22.126 + private final Pattern pat = 22.127 + Pattern.compile("(?i)(<html>)?.*?(?:package ([a-z]+);.*?(?:class ([a-z]+).*)?)?"); 22.128 + 22.129 + /** 22.130 + * Infer the file in which to write the given source. 22.131 + * @param dir the base source directory 22.132 + * @param src the source text 22.133 + * @return the file in which the source should be written 22.134 + */ 22.135 + File getSrcFile(File srcDir, String src) { 22.136 + String f; 22.137 + Matcher m = pat.matcher(src); 22.138 + if (!m.matches()) 22.139 + throw new Error("match failed"); 22.140 + if (m.group(3) != null) { 22.141 + f = m.group(2) + "/" + m.group(3) + ".java"; 22.142 + } else if (m.group(2) != null) { 22.143 + f = m.group(2) + "/" + (m.group(1) == null ? "package-info.java" : "package.html"); 22.144 + } else { 22.145 + f = "overview.html"; 22.146 + } 22.147 + return new File(srcDir, f); 22.148 + } 22.149 + 22.150 + /** 22.151 + * Get the options to give to javadoc. 22.152 + * @param srcDir the srcDir to use -overview is needed 22.153 + * @return 22.154 + */ 22.155 + List<String> getOpts(File srcDir) { 22.156 + if (!opts.isEmpty()) { 22.157 + return opts; 22.158 + } else if (sources.get(0).contains("overview")) { 22.159 + return Arrays.asList("-overview", getSrcFile(srcDir, sources.get(0)).getPath()); 22.160 + } else { 22.161 + return Collections.emptyList(); 22.162 + } 22.163 + } 22.164 + 22.165 + /** 22.166 + * Gets the output file corresponding to the first source file. 22.167 + * This file should not be written if the comment contains JavaScript and JavaScripot is 22.168 + * not allowed. 22.169 + * @param dir the base output directory 22.170 + * @return the output file 22.171 + */ 22.172 + File getOutFile(File outDir) { 22.173 + String f; 22.174 + Matcher m = pat.matcher(sources.get(0)); 22.175 + if (!m.matches()) 22.176 + throw new Error("match failed"); 22.177 + if (m.group(3) != null) { 22.178 + f = m.group(2) + "/" + m.group(3) + ".html"; 22.179 + } else if (m.group(2) != null) { 22.180 + f = m.group(2) + "/package-summary.html"; 22.181 + } else { 22.182 + f = "overview-summary.html"; 22.183 + } 22.184 + return new File(outDir, f); 22.185 + } 22.186 + 22.187 + final List<String> opts; 22.188 + final List<String> sources; 22.189 + }; 22.190 + 22.191 + enum Option { 22.192 + OFF(null), 22.193 + ON("--allow-script-in-comments"); 22.194 + 22.195 + Option(String text) { 22.196 + this.text = text; 22.197 + } 22.198 + 22.199 + final String text; 22.200 + }; 22.201 + 22.202 + private PrintStream out = System.err; 22.203 + 22.204 + public void run() throws Exception { 22.205 + int count = 0; 22.206 + for (Template template: Template.values()) { 22.207 + for (Comment comment: Comment.values()) { 22.208 + for (Option option: Option.values()) { 22.209 + if (test(template, comment, option)) { 22.210 + count++; 22.211 + } 22.212 + } 22.213 + } 22.214 + } 22.215 + 22.216 + out.println(count + " test cases run"); 22.217 + if (errors > 0) { 22.218 + throw new Exception(errors + " errors occurred"); 22.219 + } 22.220 + } 22.221 + 22.222 + boolean test(Template template, Comment comment, Option option) throws IOException { 22.223 + if (option == Option.ON && !comment.hasScript) { 22.224 + // skip --allowScriptInComments if comment does not contain JavaScript 22.225 + return false; 22.226 + } 22.227 + 22.228 + String test = template + "-" + comment + "-" + option; 22.229 + out.println("Test: " + test); 22.230 + 22.231 + File dir = new File(test); 22.232 + dir.mkdirs(); 22.233 + File srcDir = new File(dir, "src"); 22.234 + File outDir = new File(dir, "out"); 22.235 + 22.236 + String alert = "alert(\"" + test + "\");"; 22.237 + for (String src: template.sources) { 22.238 + writeFile(template.getSrcFile(srcDir, src), 22.239 + src.replace("#COMMENT", 22.240 + "/** " + comment.text.replace("#ALERT", alert) + " **/")); 22.241 + } 22.242 + 22.243 + List<String> opts = new ArrayList<String>(); 22.244 + opts.add("-sourcepath"); 22.245 + opts.add(srcDir.getPath()); 22.246 + opts.add("-d"); 22.247 + opts.add(outDir.getPath()); 22.248 + if (option.text != null) 22.249 + opts.add(option.text); 22.250 + for (String opt: template.getOpts(srcDir)) { 22.251 + opts.add(opt.replace("#COMMENT", comment.text.replace("#ALERT", alert))); 22.252 + } 22.253 + opts.addAll(comment.opts); 22.254 + opts.add("-noindex"); // index not required; save time/space writing files 22.255 + opts.add("p"); 22.256 + 22.257 + StringWriter sw = new StringWriter(); 22.258 + PrintWriter pw = new PrintWriter(sw); 22.259 + int rc = javadoc(opts, pw); 22.260 + pw.close(); 22.261 + String log = sw.toString(); 22.262 + writeFile(new File(dir, "log.txt"), log); 22.263 + 22.264 + out.println("opts: " + opts); 22.265 + out.println(" rc: " + rc); 22.266 + out.println(" log:"); 22.267 + out.println(log); 22.268 + 22.269 + String ERROR = "Use --allow-script-in-comment"; 22.270 + File outFile = template.getOutFile(outDir); 22.271 + 22.272 + boolean expectErrors = comment.hasScript && (option == Option.OFF); 22.273 + 22.274 + if (expectErrors) { 22.275 + check(rc != 0, "unexpected exit code: " + rc); 22.276 + check(log.contains(ERROR), "expected error message not found"); 22.277 + check(!outFile.exists(), "output file found unexpectedly"); 22.278 + } else { 22.279 + check(rc == 0, "unexpected exit code: " + rc); 22.280 + check(!log.contains(ERROR), "error message found"); 22.281 + check(outFile.exists(), "output file not found"); 22.282 + } 22.283 + 22.284 + out.println(); 22.285 + return true; 22.286 + } 22.287 + 22.288 + int javadoc(List<String> opts, PrintWriter pw) { 22.289 + return com.sun.tools.javadoc.Main.execute("javadoc", pw, pw, pw, 22.290 + "com.sun.tools.doclets.standard.Standard", opts.toArray(new String[opts.size()])); 22.291 + } 22.292 + 22.293 + File writeFile(File f, String text) throws IOException { 22.294 + f.getParentFile().mkdirs(); 22.295 + FileWriter fw = new FileWriter(f); 22.296 + try { 22.297 + fw.write(text); 22.298 + } finally { 22.299 + fw.close(); 22.300 + } 22.301 + return f; 22.302 + } 22.303 + 22.304 + void check(boolean cond, String errMessage) { 22.305 + if (!cond) { 22.306 + error(errMessage); 22.307 + } 22.308 + } 22.309 + 22.310 + void error(String message) { 22.311 + out.println("Error: " + message); 22.312 + errors++; 22.313 + } 22.314 + 22.315 + int errors = 0; 22.316 +} 22.317 +