Summary
-------
Adds a JDK property for determining the behavior of a processor when DTD is encountered. The property complements the existing DTD-related properties with a uniformed support across JAXP processors, and by providing a system property that can be placed in the JAXP Configuration File.
Problem
-------
DTD (Document Type Definition) is one of the main sources of vulnerability in XML processing. As a mitigation, the JDK supports two properties, disallow-doctype-decl (fully qualified name: `http://apache.org/xml/features/disallow-doctype-decl`) and supportDTD (`javax.xml.stream.supportDTD`), that can be used to instruct the processors to either deny or ignore the DTD. However, there are several issues concerning these properties.
First, the properties are not consistently defined. The disallow-doctype-decl property was originally introduced in the JDK as an undocumented and unsupported property from the underlying Apache implementation for DOM and SAX parsers. The supportDTD property, on the other hand, was a standard SE property from the StAX API.
Second, the behaviors of the two properties are different. The disallow-doctype-decl property instructs the processors to deny the DTD by throwing an Exception. This means that the parser will stop the process and report an error. The supportDTD property, in contrast, allows the processor to continue processing by ignoring the DTD.
Furthermore, the properties did not have corresponding system properties, that make them unable to be set without code changes or in the JAXP Configuration File.
Solution
--------
Add an implementation specific DTD property `jdk.xml.dtd.support` to be supported by all JAXP processors, including DOM, SAX and StAX parsers, XML Validator and Transformer. Add a System Property with the same name, so that it can be set with or without code changes as a Java System Property or in the JAXP Configuration File.
The DTD property is supported by JAXP processors including DOM, SAX, StAX, Validation and Transform. It can be set on any of the factories or processors, or as a System Property or in the JAXP Configuration File to take effect on the processors.
The property covers the functions of both `disallow-doctype-decl` and `supportDTD` by providing three values that are deny, ignore and allow. The combination of `deny` and `allow` is equivalent to setting disallow-doctype-decl to true or false, while `ignore` and `allow` is equivalent to setting supportDTD to false or true. As a result, setting the DTD property to `deny` would have the same effect as setting `disallow-doctype-decl` to true, while setting it to `ignore` would instruct the StAX process to behave as if `supportDTD` is set to false.
Because the property is uniformly supported, the three-value setting does expand the new property's functions, that is, `ignore` over disallow-doctype-decl and `deny` over `supportDTD`. For DOM/SAX parsers that supported `disallow-doctype-decl`, they will now gain the ability to ignore DTDs in addition to `disallow` (or deny), while for StAX, that supported the `supportDTD` property, it may now deny DTDs in addition to `ignore`.
The new DTD property is secondary to the existing properties in terms of property precedence. However it may be set, that is, via a factory, as a System Property, or in the configuration file, it will have no effect if the `supportDTD` property is already set on the StAX factory, or the `disallow-doctype-decl` property on a DOM or SAX factory.
Overall, this solution provides a universal property that can be used in the redefined JAXP Configuration File (JDK-8303530) to control how DTDs are processed.
Specification
-------------
**Property DTD**
**Definition**: instructs a parser to handle DTDs in accordance with the setting of this property. The options are `allow` to continue processing, `ignore` to skip the DTD, and `deny` to stop processing by reporting an error.
**Name**: `jdk.xml.dtd.support`
**System Property**: `jdk.xml.dtd.support`
**Configuration File**: yes. This property can be placed in the JAXP Configuration File using the System Property as key. An entry in the configuration file will be as follows:
jdk.xml.dtd.support=deny
**Value**: valid values are `allow`, `ignore`, and `deny`. Values are case-insensitive.
**Default Value**: `allow`.
**Processor Support**: DOM and SAX parsers defined in package `javax.xml.parsers`, StAX parsers in `javax.xml.stream`, XML Validator in `javax.xml.validation`, and Transformer in `javax.xml.transform`. The following is an example of setting the property on the DOM processor:
```
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setAttribute("jdk.xml.dtd.support", "deny");
```
**Error handling**: when the property is set to `deny`, an exception is expected to be thrown when a DTD is encountered. The specific exception is as defined by the relevant processor, for DOM and SAX for example, it is `org.xml.sax.XMLParseException` as specified in `javax.xml.parsers.DocumentBuilder` and `SAXParser`. When the property is set to `ignore`, the processor will skip the DTDs. There will be no errors reported even if the DTDs contain elements that would otherwise raise an exception, for example, forbidden external references, as the entire DTD is skipped. When the property is set to `allow`, the processor will continue processing DTDs as usual, any errors arising from the process will be reported as specified by the processors. Setting the property with values other than the values defined will cause the factories to throw exceptions as specified by the relevant factories.
**Note**: this property complements the two existing DTD-related properties, disallow-doctype-decl (fully qualified name: `http://apache.org/xml/features/disallow-doctype-decl`) and supportDTD (`javax.xml.stream.supportDTD`), by providing a uniformed support for the processors listed in Processor Support and a system property that can be used in the JAXP Configuration File. When disallow-doctype-decl is set on the DOM or SAX factory, or supportDTD on StAX factory, this property will have no effect.
These three properties control whether DTDs as a whole shall be processed. When they are set to deny or ignore, other properties that regulate a part or an aspect of DTD shall have no effect.
<hr>
This change is documented in the module-summary. The new property is added alongside properties for which the rules have been defined previously (refer to JDK-8303531). Below is the diff:
```
--- a/src/java.xml/share/classes/module-info.java
+++ b/src/java.xml/share/classes/module-info.java
@@ -752,7 +752,7 @@
* <td id="ExtFunc">{@systemProperty jdk.xml.enableExtensionFunctions}</td>
* <td>Determines if XSLT and XPath extension functions are to be allowed.
* </td>
- * <td style="text-align:center" rowspan="3">yes</td>
+ * <td style="text-align:center" rowspan="4">yes</td>
* <td style="text-align:center" rowspan="3">Boolean</td>
* <td>
* true or false. True indicates that extension functions are allowed; False otherwise.
@@ -808,6 +808,40 @@
* <td style="text-align:center"><a href="#Processor">Method 2</a></td>
* <td style="text-align:center">9</td>
* </tr>
+ * <tr>
+ * <td id="DTD">{@systemProperty jdk.xml.dtd.support}<a href="#Note7">[7]</a></td>
+ * <td>Instructs the parser to handle DTDs in accordance with the setting of this property.
+ * The options are:
+ * <ul>
+ * <li><p>
+ * {@code allow} -- indicates that the parser shall continue processing DTDs;
+ * </li>
+ * <li><p>
+ * {@code ignore} -- indicates that the parser shall skip DTDs;
+ * </li>
+ * <li><p>
+ * {@code deny} -- indicates that the parser shall reject DTDs as an error.
+ * The parser shall report the error in accordance with its relevant specification.
+ * </li>
+ * </ul>
+ * </td>
+ * <td style="text-align:center">String</td>
+ * <td>
+ * {@code allow, ignore, and deny}. Values are case-insensitive.
+ * </td>
+ * <td style="text-align:center">allow</td>
+ * <td style="text-align:center">No</td>
+ * <td style="text-align:center">Yes</td>
+ * <td style="text-align:center">
+ * <a href="#DOM">DOM</a><br>
+ * <a href="#SAX">SAX</a><br>
+ * <a href="#StAX">StAX</a><br>
+ * <a href="#Validation">Validation</a><br>
+ * <a href="#Transform">Transform</a>
+ * </td>
+ * <td style="text-align:center"><a href="#Processor">Method 1</a></td>
+ * <td style="text-align:center">22</td>
+ * </tr>
* </tbody>
* </table>
* <p id="Note1">
@@ -838,6 +872,19 @@
* are as shown in the table <a href="#Processor">Processors</a>.
* <p id="Note6">
* <b>[6]</b> Indicates the initial release the property is introduced.
+ * <p id="Note7">
+ * <b>[7]</b> The {@code jdk.xml.dtd.support} property complements the two existing
+ * DTD-related properties, {@code disallow-doctype-decl}(fully qualified name:
+ * {@code http://apache.org/xml/features/disallow-doctype-decl}) and supportDTD
+ * ({@code javax.xml.stream.supportDTD}), by providing a uniformed support for the
+ * processors listed and a system property that can be used in the
+ * <a href="#Conf_CF">JAXP Configuration File</a>. When {@code disallow-doctype-decl} is
+ * set on the DOM or SAX factory, or supportDTD on StAX factory, the {@code jdk.xml.dtd.support}
+ * property will have no effect.
+ * <p>
+ * These three properties control whether DTDs as a whole shall be processed. When
+ * they are set to deny or ignore, other properties that regulate a part or an
+ * aspect of DTD shall have no effect.
*
* <h3 id="IN_Legacy">Legacy Property Names (deprecated)</h3>
* JDK releases prior to JDK 17 support the use of URI style prefix for properties.
```