[PATCH]: possible fixes for resolve-dtd-uris inconsistency

Michael Glavassevich <[email protected]> Thu, 22 Apr 2004 00:32:24 -0400
Newsgroups gmane.text.xml.sax.devel
Message-ID <OFEA30116C.15E9284F-ON85256E7E.0013FB5E-85256E7E.0018F28B@ca.ibm.com>
[originally posted on 2004-03-11]

The 1.1 extensions add a new feature called resolve-dtd-uris which 
determines whether system IDs reported in DTDHandler and DeclHandler are 
resolved against a base URI. 

From the package description (in CVS) for org.xml.sax, it says this about 
resolve-dtd-uris: 

"A value of "true" indicates that system IDs in declarations will be 
absolutized (relative to their base URIs) before reporting. (That is the 
default behavior for all SAX2 XML parsers.) A value of "false" indicates 
those IDs will not be absolutized; parsers will provide the base URI from 
Locator.getSystemId(). This applies to system IDs passed in 
  - DTDHandler.notationDecl(), 
  - DTDHandler.unparsedEntityDecl(), and 
  - DeclHandler.externalEntityDecl(). 
It does not apply to EntityResolver.resolveEntity(), which is not used to 
report declarations, or to LexicalHandler.startDTD(), which already 
provides the non-absolutized URI." 

This default behaviour is fine for DTDHandler. The javadoc for both 
DTDHandler.notationDecl() and DTDHandler.unparsedEntityDecl() says that: 
"If the system identifier is a URL, the parser must resolve it fully 
before passing it to the application." However the javadoc for 
DeclHandler.externalEntityDecl() says nothing of the sort. It specifies 
that the systemId parameter is: "the declared system identifier of the 
entity". I would interpret that to be the literal system identifier as it 
was specified in the document, not the result of resolving this against a 
base URI. The description for LexicalHandler.startDTD() (which isn't 
affected by this feature) is similar. It says that the systemId parameter 
is: "The declared system identifier for the external DTD subset, or null 
if none was declared".

There's an inconsistency here which should be resolved. Was it always 
intended that the systemId passed to DeclHandler.externalEntityDecl() be 
fully resolved, even though the text doesn't seem to imply that? If not, 
why are system IDs passed to this method affected by this feature? 

-----------------------------------------------------

Here are some possible fixes.

The first (org.xml.sax.package.html.diff) drops 
DeclHandler.externalEntityDecl from the list of methods affected by the 
resolve-dtd-uris feature.

The second (org.xml.sax.ext.DeclHandler.java.diff) aligns the description 
of DeclHandler.externalEntityDecl with DTDHandler.unparsedEntityDecl, 
requiring that the parser absolutize the system identifier, though this is 
backwards incompatible and may affect some real world users who expect the 
declared system identifier even if it was always intended that the system 
id passed to DeclHandler.externalEntityDecl be fully resolved.

Karl had another suggestion (2004-03-31): 

"Maybe it could be settled this way:

If the application reads or sets the "resolve-dtd-uris" feature,
then the parser is bound by its current documentation. However, 
in its initial state the parser works as as originally documented.
Obviously there would be no documented way to reset the parser
to its inital state, and one would have to create a new instance
for that purpose.

This would allow legacy application to work.
(not an elegant solution)"



Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: [email protected]
E-mail: [email protected]
org.xml.sax.package.html.diff (application/octet-stream, 881 B)
Index: sax2/src/org/xml/sax/package.html
===================================================================
RCS file: /cvsroot/sax/sax2/src/org/xml/sax/package.html,v
retrieving revision 1.18
diff -u -r1.18 package.html
--- sax2/src/org/xml/sax/package.html	21 Apr 2004 13:06:01 -0000	1.18
+++ sax2/src/org/xml/sax/package.html	22 Apr 2004 03:13:11 -0000
@@ -99,9 +99,8 @@
 	    parsers will provide the base URI from
 	    <em>Locator.getSystemId()</em>.
 	    This applies to system IDs passed in <ul>
-		<li><em>DTDHandler.notationDecl()</em>,
-		<li><em>DTDHandler.unparsedEntityDecl()</em>, and
-		<li><em>DeclHandler.externalEntityDecl()</em>.
+		<li><em>DTDHandler.notationDecl()</em>, and
+		<li><em>DTDHandler.unparsedEntityDecl()</em>.
 	    </ul>
 	    It does not apply to <em>EntityResolver.resolveEntity()</em>,
 	    which is not used to report declarations, or to
org.xml.sax.ext.DeclHandler.java.diff (application/octet-stream, 1.2 KB)
Index: sax2/src/org/xml/sax/ext/DeclHandler.java
===================================================================
RCS file: /cvsroot/sax/sax2/src/org/xml/sax/ext/DeclHandler.java,v
retrieving revision 1.5
diff -u -r1.5 DeclHandler.java
--- sax2/src/org/xml/sax/ext/DeclHandler.java	30 Jan 2002 21:00:37 -0000	1.5
+++ sax2/src/org/xml/sax/ext/DeclHandler.java	22 Apr 2004 03:21:54 -0000
@@ -125,11 +125,14 @@
      * <p>Only the effective (first) declaration for each entity
      * will be reported.</p>
      *
+     * <p>If the system identifier is a URL, the parser must resolve it
+     * fully before passing it to the application.</p>
+     *
      * @param name The name of the entity.  If it is a parameter
      *        entity, the name will begin with '%'.
-     * @param publicId The declared public identifier of the entity, or
-     *        null if none was declared.
-     * @param systemId The declared system identifier of the entity.
+     * @param publicId The entity's public identifier, or null if none
+     *        was given.
+     * @param systemId The entity's system identifier.
      * @exception SAXException The application may raise an exception.
      * @see #internalEntityDecl
      * @see org.xml.sax.DTDHandler#unparsedEntityDecl