From b0c088c464ea6dd9dc76f5f40e2f9119c7df114a Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Mon, 29 Apr 2024 19:54:03 -0700 Subject: [PATCH 1/2] Start 6.7 branch --- pom.xml | 2 +- release-notes/VERSION | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e23cc6e..029d13d 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ com.fasterxml.woodstox woodstox-core - 6.6.3-SNAPSHOT + 6.7.0-SNAPSHOT bundle Woodstox Woodstox is a high-performance XML processor that implements Stax (JSR-173), diff --git a/release-notes/VERSION b/release-notes/VERSION index 4a33a79..42b68d7 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -4,6 +4,10 @@ Project: woodstox === Releases === ------------------------------------------------------------------------ +6.7.0 (not yet released) + +- + 6.6.2 (26-Mar-2024) #200: Fix shading of `isorelax` dependency (and other msv-core components) From 17a3eb2c226d128255ee19ee871d419e93192816 Mon Sep 17 00:00:00 2001 From: Stanimir Stamenkov <1247730+stanio@users.noreply.github.com> Date: Tue, 30 Apr 2024 05:52:43 +0300 Subject: [PATCH 2/2] WstxEventFactory: Ensure events' immutable non-null location (#205) --- release-notes/CREDITS | 5 + release-notes/VERSION | 3 +- .../com/ctc/wstx/stax/WstxEventFactory.java | 25 +++++ .../evt/TestEventFactoryLocation.java | 98 +++++++++++++++++++ 4 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 src/test/java/wstxtest/evt/TestEventFactoryLocation.java diff --git a/release-notes/CREDITS b/release-notes/CREDITS index 66d11da..013d3e6 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -104,3 +104,8 @@ Alexey Gavrilov (@agavrilov76) Jeremy Norris (@norrisjeremy) * Reported #200: Fix shading of `isorelax` dependency (and other msv-core components) (6.6.2) + +Stanimir Stamenkov (@stanio) + +* Reported, provided fix for #204: Non-conformant `XMLEventFactory.setLocation(null)` + (7.0.0) diff --git a/release-notes/VERSION b/release-notes/VERSION index 42b68d7..3d233c4 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -6,7 +6,8 @@ Project: woodstox 6.7.0 (not yet released) -- +#204: Non-conformant `XMLEventFactory.setLocation(null)` + (fix provided by Stanimir S) 6.6.2 (26-Mar-2024) diff --git a/src/main/java/com/ctc/wstx/stax/WstxEventFactory.java b/src/main/java/com/ctc/wstx/stax/WstxEventFactory.java index f19adf1..95067cf 100644 --- a/src/main/java/com/ctc/wstx/stax/WstxEventFactory.java +++ b/src/main/java/com/ctc/wstx/stax/WstxEventFactory.java @@ -23,10 +23,12 @@ import javax.xml.stream.events.*; import aQute.bnd.annotation.spi.ServiceProvider; +import org.codehaus.stax2.XMLStreamLocation2; import org.codehaus.stax2.ri.Stax2EventFactoryImpl; import com.ctc.wstx.compat.QNameCreator; import com.ctc.wstx.evt.*; +import com.ctc.wstx.io.WstxInputLocation; /** * Implementation of {@link XMLEventFactory} to be used with @@ -38,6 +40,7 @@ public final class WstxEventFactory { public WstxEventFactory() { super(); + super.setLocation(WstxInputLocation.getEmptyLocation()); } /* @@ -46,6 +49,28 @@ public WstxEventFactory() { ///////////////////////////////////////////////////////////// */ + @Override + public void setLocation(Location location) { + super.setLocation(location == null ? WstxInputLocation.getEmptyLocation() + : immutableLocation(location)); + } + + private static WstxInputLocation immutableLocation(Location location) { + if (location == null) { + return null; + } + if (location.getClass() == WstxInputLocation.class) { + return (WstxInputLocation) location; + } + + WstxInputLocation context = (location instanceof XMLStreamLocation2) + ? immutableLocation(((XMLStreamLocation2) location).getContext()) + : null; + return new WstxInputLocation(context, location.getPublicId(), + location.getSystemId(), location.getCharacterOffset(), + location.getLineNumber(), location.getColumnNumber()); + } + //public Attribute createAttribute(QName name, String value) //public Attribute createAttribute(String localName, String value) //public Attribute createAttribute(String prefix, String nsURI, String localName, String value) diff --git a/src/test/java/wstxtest/evt/TestEventFactoryLocation.java b/src/test/java/wstxtest/evt/TestEventFactoryLocation.java new file mode 100644 index 0000000..868b922 --- /dev/null +++ b/src/test/java/wstxtest/evt/TestEventFactoryLocation.java @@ -0,0 +1,98 @@ +package wstxtest.evt; + +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.Objects; + +import javax.xml.stream.Location; +import javax.xml.stream.events.XMLEvent; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; +import org.junit.Before; +import org.junit.Test; + +import com.ctc.wstx.io.WstxInputLocation; +import com.ctc.wstx.stax.WstxEventFactory; + +public class TestEventFactoryLocation { + + private WstxEventFactory eventFactory; + + @Before + public void setUp() { + eventFactory = new WstxEventFactory(); + } + + @Test + public void testDefaultLocation() { + XMLEvent event = eventFactory.createStartDocument(); + + assertThat("event.location", event.getLocation(), unknownLocation()); + } + + @Test + public void testResetLocation() { + eventFactory.setLocation(new WstxInputLocation(null, null, "about:blank", 3L, 2, 1)); + eventFactory.setLocation(null); + + XMLEvent event = eventFactory.createStartElement("foo", "bar", "baz"); + + assertThat("event.location", event.getLocation(), unknownLocation()); + } + + @Test + public void testNonVolatileLocation() { + VolatileLocation volatileLocation = new VolatileLocation(2, 3); + eventFactory.setLocation(volatileLocation); + + XMLEvent event = eventFactory.createEndElement("foo", "bar", "baz"); + volatileLocation.line = 4; + volatileLocation.col = 5; + + assertThat("event.location", event.getLocation(), + locationWithProperties(null, null, -1, 2, 3)); + } + + private static Matcher unknownLocation() { + // XXX: Not sure if the empty-string publicId/systemId are conformant + //return locationWithProperties(null, null, -1, -1, -1); + return locationWithProperties("", "", -1, -1, -1); + } + + private static Matcher locationWithProperties(final String pubId, + final String sysId, final int charOffset, final int row, final int col) { + return new TypeSafeMatcher() { + @Override public void describeTo(Description description) { + description.appendText("Location(publicId: ").appendValue(pubId) + .appendText(", systemId: ").appendValue(sysId) + .appendText(", characterOffset: ").appendValue(charOffset) + .appendText(", lineNumber: ").appendValue(row) + .appendText(", columnNumber: ").appendValue(col); + } + + @Override protected boolean matchesSafely(Location item) { + return Objects.equals(item.getPublicId(), pubId) + && Objects.equals(item.getSystemId(), sysId) + && Objects.equals(item.getCharacterOffset(), charOffset) + && Objects.equals(item.getLineNumber(), row) + && Objects.equals(item.getColumnNumber(), col); + } + }; + } + + static class VolatileLocation implements Location { + int line; + int col; + VolatileLocation(int line, int col) { + this.line = line; + this.col = col; + } + @Override public String getPublicId() { return null; } + @Override public String getSystemId() { return null; } + @Override public int getLineNumber() { return line; } + @Override public int getColumnNumber() { return col; } + @Override public int getCharacterOffset() { return -1; } + } +}