Skip to content

Commit

Permalink
Fix #108
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed May 14, 2020
1 parent 861b8c8 commit 90eb52f
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 55 deletions.
3 changes: 2 additions & 1 deletion release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ Project: woodstox
=== Releases ===
------------------------------------------------------------------------

6.2.1 (not yet released)
6.2.1 (14-May-2020)

#107: Sub-optimal exception with `WstxOutputProperties.P_OUTPUT_VALIDATE_NAMES`
#108: Repairing `XMLStreamWriter` tries to bind `xml` namespace URI

6.2.0 (25-Apr-2020)

Expand Down
60 changes: 33 additions & 27 deletions src/main/java/com/ctc/wstx/sw/OutputElementBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ public abstract class OutputElementBase
public final static int PREFIX_OK = 1;
public final static int PREFIX_MISBOUND = 2;

final static String sXmlNsPrefix = XMLConstants.XML_NS_PREFIX;
final static String sXmlNsURI = XMLConstants.XML_NS_URI;
protected final static String sXmlNsPrefix = XMLConstants.XML_NS_PREFIX;
protected final static String sXmlNsURI = XMLConstants.XML_NS_URI;

// @since 4.2.1
protected final static BijectiveNsMap DEFAULT_XML_BINDINGS = BijectiveNsMap.createEmpty();

/*
////////////////////////////////////////////
Expand Down Expand Up @@ -143,14 +146,16 @@ public final String getDefaultNsUri() {
*/
public final String getExplicitPrefix(String uri)
{
if (mNsMapping != null) {
String prefix = mNsMapping.findPrefixByUri(uri);
if (prefix != null) {
return prefix;
}
BijectiveNsMap mappings = mNsMapping;
if (mappings == null) {
mappings = DEFAULT_XML_BINDINGS;
}
String prefix = mappings.findPrefixByUri(uri);
if (prefix != null) {
return prefix;
}
if (mRootNsContext != null) {
String prefix = mRootNsContext.getPrefix(uri);
prefix = mRootNsContext.getPrefix(uri);
if (prefix != null) {
// Hmmh... still can't use the default NS:
if (prefix.length() > 0) {
Expand Down Expand Up @@ -188,9 +193,8 @@ public final int isPrefixValid(String prefix, String nsURI,
nsURI = "";
}

/* First thing is to see if specified prefix is bound to a namespace;
* and if so, verify it matches with data passed in:
*/
// First thing is to see if specified prefix is bound to a namespace;
// and if so, verify it matches with data passed in:

// Checking default namespace?
if (prefix == null || prefix.length() == 0) {
Expand All @@ -200,19 +204,17 @@ public final int isPrefixValid(String prefix, String nsURI,
return PREFIX_OK;
}
} else {
/* Attributes never use the default namespace: "no prefix"
* can only mean "no namespace"
*/
// Attributes never use the default namespace: "no prefix"
// can only mean "no namespace"
if (nsURI.length() == 0) {
return PREFIX_OK;
}
}
return PREFIX_MISBOUND;
}

/* Need to handle 'xml' prefix and its associated
* URI; they are always declared by default
*/
// Need to handle 'xml' prefix and its associated
// URI; they are always declared by default
if (prefix.equals(sXmlNsPrefix)) {
// Should we thoroughly verify its namespace matches...?
// 01-Apr-2005, TSa: Yes, let's always check this
Expand Down Expand Up @@ -298,11 +300,13 @@ public final String getNamespaceURI(String prefix)
if (prefix.length() == 0) { //default NS
return mDefaultNsURI;
}
if (mNsMapping != null) {
String uri = mNsMapping.findUriByPrefix(prefix);
if (uri != null) {
return uri;
}
BijectiveNsMap mappings = mNsMapping;
if (mappings == null) {
mappings = DEFAULT_XML_BINDINGS;
}
String uri = mappings.findUriByPrefix(prefix);
if (uri != null) {
return uri;
}
return (mRootNsContext != null) ?
mRootNsContext.getNamespaceURI(prefix) : null;
Expand All @@ -314,11 +318,13 @@ public final String getPrefix(String uri)
if (mDefaultNsURI.equals(uri)) {
return "";
}
if (mNsMapping != null) {
String prefix = mNsMapping.findPrefixByUri(uri);
if (prefix != null) {
return prefix;
}
BijectiveNsMap mappings = mNsMapping;
if (mappings == null) {
mappings = DEFAULT_XML_BINDINGS;
}
String prefix = mappings.findPrefixByUri(uri);
if (prefix != null) {
return prefix;
}
return (mRootNsContext != null) ?
mRootNsContext.getPrefix(uri) : null;
Expand Down
36 changes: 16 additions & 20 deletions src/main/java/com/ctc/wstx/sw/RepairingNsStreamWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,11 @@ public void doSetPrefix(String prefix, String uri)
public void writeStartElement(StartElement elem)
throws XMLStreamException
{
/* In repairing mode this is simple: let's just pass info
* we have, and things should work... a-may-zing!
*/
// In repairing mode this is simple: let's just pass info
// we have, and things should work... a-may-zing!
QName name = elem.getName();
writeStartElement(name.getPrefix(), name.getLocalPart(),
name.getNamespaceURI());
@SuppressWarnings("unchecked")
Iterator<Attribute> it = elem.getAttributes();
while (it.hasNext()) {
Attribute attr = it.next();
Expand Down Expand Up @@ -494,7 +492,7 @@ protected final String findElemPrefix(String nsURI, SimpleOutputElement elem)
* to create and bind a namespace mapping for specified namespace.
*/
protected final String generateElemPrefix(String suggPrefix, String nsURI,
SimpleOutputElement elem)
SimpleOutputElement elem)
throws XMLStreamException
{
/* Ok... now, since we do not have an existing mapping, let's
Expand Down Expand Up @@ -551,7 +549,7 @@ protected final String generateElemPrefix(String suggPrefix, String nsURI,
* will be added.
*/
protected final String findOrCreateAttrPrefix(String suggPrefix, String nsURI,
SimpleOutputElement elem)
SimpleOutputElement elem)
throws XMLStreamException
{
if (nsURI == null || nsURI.length() == 0) {
Expand All @@ -568,17 +566,17 @@ protected final String findOrCreateAttrPrefix(String suggPrefix, String nsURI,
return suggPrefix;
}
/* Otherwise, if the prefix is unbound, let's just bind
* it -- if caller specified a prefix, it probably prefers
* binding that prefix even if another prefix already existed?
* The remaining case (already bound to another URI) we don't
* want to touch, at least not yet: it may or not be safe
* to change binding, so let's just not try it.
*/
* it -- if caller specified a prefix, it probably prefers
* binding that prefix even if another prefix already existed?
* The remaining case (already bound to another URI) we don't
* want to touch, at least not yet: it may or not be safe
* to change binding, so let's just not try it.
*/
if (status == SimpleOutputElement.PREFIX_UNBOUND) {
elem.addPrefix(suggPrefix, nsURI);
doWriteNamespace(suggPrefix, nsURI);
return suggPrefix;
}
elem.addPrefix(suggPrefix, nsURI);
doWriteNamespace(suggPrefix, nsURI);
return suggPrefix;
}
}

// If not, perhaps there's another existing binding available?
Expand All @@ -587,14 +585,12 @@ protected final String findOrCreateAttrPrefix(String suggPrefix, String nsURI,
return prefix;
}

/* Nope, need to create one. First, let's see if there's a
* preference...
*/
// Nope, need to create one. First, let's see if there's a preference...
if (suggPrefix != null) {
prefix = suggPrefix;
} else if (mSuggestedPrefixes != null) {
prefix = mSuggestedPrefixes.get(nsURI);
// note: def ns is never added to suggested prefix map
// note: def ns is never added to suggested prefix map
}

if (prefix != null) {
Expand Down
6 changes: 2 additions & 4 deletions src/main/java/com/ctc/wstx/util/BijectiveNsMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
* Currently only used by stream writers, but could be more generally useful
* too.
*/

public final class BijectiveNsMap
{
/*
Expand Down Expand Up @@ -91,9 +90,8 @@ public static BijectiveNsMap createEmpty()
strs[2] = XMLConstants.XMLNS_ATTRIBUTE;
strs[3] = XMLConstants.XMLNS_ATTRIBUTE_NS_URI;

/* Let's consider pre-defined ones to be 'out of scope', i.e.
* conceptually be part of (missing) parent's mappings.
*/
// Let's consider pre-defined ones to be 'out of scope', i.e.
// conceptually be part of (missing) parent's mappings.
return new BijectiveNsMap(4, strs);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@ public void testElements()

w.writeStartDocument();

/* Calling setPrefix() should be optional; but if we call it,
* exceptation is that it does properly cause URL to be bound.
*/
// Calling setPrefix() should be optional; but if we call it,
// expectation is that it does properly cause URL to be bound.
w.setPrefix("p1", URL_P1);
w.writeStartElement(URL_P1, "test");

Expand Down Expand Up @@ -441,4 +440,34 @@ public void testOptimalNonDefaultNsDecls()

sr.close();
}

public void testPreBoundXmlNamespaceAsAttribute()
throws IOException, XMLStreamException
{
StringWriter strw = new StringWriter();
XMLStreamWriter w = getRepairingWriter(strw);
w.writeStartDocument();
w.writeStartElement("test");
w.writeAttribute(javax.xml.XMLConstants.XML_NS_URI, "lang", "en-US");
w.writeEndElement();
w.writeEndDocument();
w.close();
final String XML = strw.toString().trim();
assertEquals("<?xml version='1.0' encoding='UTF-8'?><test xml:lang=\"en-US\"/>", XML);
}

public void testPreBoundXmlNamespaceAsElement()
throws IOException, XMLStreamException
{
StringWriter strw = new StringWriter();
XMLStreamWriter w = getRepairingWriter(strw);
w.writeStartDocument();
w.writeStartElement(javax.xml.XMLConstants.XML_NS_URI, "test");
w.writeEndElement();
w.writeEndDocument();
w.close();

final String XML = strw.toString().trim();
assertEquals("<?xml version='1.0' encoding='UTF-8'?><xml:test/>", XML);
}
}

0 comments on commit 90eb52f

Please sign in to comment.