You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2017/06/15 16:40:59 UTC
[09/15] cxf git commit: Merge pull request #1 from
exabrial/TRIBESTRM_3972_CVE_2016_8739
Merge pull request #1 from exabrial/TRIBESTRM_3972_CVE_2016_8739
[Tribestrm-3972] cve-2016-8739
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/73963a76
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/73963a76
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/73963a76
Branch: refs/heads/2.6.x-fixes
Commit: 73963a760286eeacc425f4cd366b7dd8dbf20795
Parents: 6caf791
Author: Tod Bookless <tb...@tomitribe.com>
Authored: Thu Jun 1 10:26:13 2017 -0700
Committer: Jonathan S. Fisher <jf...@tomitribe.com>
Committed: Wed Jun 7 15:11:55 2017 -0500
----------------------------------------------------------------------
.../provider/atom/AbstractAtomProvider.java | 21 +-
.../jaxrs/provider/atom/AtomPojoProvider.java | 38 ++--
.../provider/atom/AtomPojoProviderTest.java | 202 ++++++++++++++-----
3 files changed, 187 insertions(+), 74 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/73963a76/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AbstractAtomProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AbstractAtomProvider.java b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AbstractAtomProvider.java
index ba65698..203e6ed 100644
--- a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AbstractAtomProvider.java
+++ b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AbstractAtomProvider.java
@@ -31,6 +31,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
+import javax.xml.stream.XMLStreamReader;
import org.apache.abdera.Abdera;
import org.apache.abdera.model.Document;
@@ -39,28 +40,29 @@ import org.apache.abdera.parser.Parser;
import org.apache.abdera.parser.ParserOptions;
import org.apache.abdera.writer.Writer;
import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.staxutils.StaxUtils;
-public abstract class AbstractAtomProvider<T extends Element>
+public abstract class AbstractAtomProvider<T extends Element>
implements MessageBodyWriter<T>, MessageBodyReader<T> {
private static final Logger LOG = LogUtils.getL7dLogger(AbstractAtomProvider.class);
private static final Abdera ATOM_ENGINE = new Abdera();
private boolean autodetectCharset;
private boolean formattedOutput;
-
+
public long getSize(T element, Class<?> type, Type genericType, Annotation[] annotations, MediaType mt) {
return -1;
}
- public void writeTo(T element, Class<?> clazz, Type type, Annotation[] a,
- MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os)
+ public void writeTo(T element, Class<?> clazz, Type type, Annotation[] a,
+ MediaType mt, MultivaluedMap<String, Object> headers, OutputStream os)
throws IOException {
if (MediaType.APPLICATION_JSON_TYPE.isCompatible(mt)) {
Writer w = createWriter("json");
if (w == null) {
throw new WebApplicationException(415);
}
- element.writeTo(w, os);
+ element.writeTo(w, os);
} else if (formattedOutput) {
Writer w = createWriter("prettyxml");
if (w != null) {
@@ -80,9 +82,9 @@ public abstract class AbstractAtomProvider<T extends Element>
}
return w;
}
-
- public T readFrom(Class<T> clazz, Type t, Annotation[] a, MediaType mt,
- MultivaluedMap<String, String> headers, InputStream is)
+
+ public T readFrom(Class<T> clazz, Type t, Annotation[] a, MediaType mt,
+ MultivaluedMap<String, String> headers, InputStream is)
throws IOException {
Parser parser = ATOM_ENGINE.getParser();
synchronized (parser) {
@@ -91,7 +93,8 @@ public abstract class AbstractAtomProvider<T extends Element>
options.setAutodetectCharset(autodetectCharset);
}
}
- Document<T> doc = parser.parse(is);
+ XMLStreamReader reader = StaxUtils.createXMLStreamReader(is);
+ Document<T> doc = parser.parse(reader);
return doc.getRoot();
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/73963a76/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProvider.java
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProvider.java b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProvider.java
index bfb5a78..dcb870b 100644
--- a/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProvider.java
+++ b/rt/rs/extensions/providers/src/main/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProvider.java
@@ -558,8 +558,8 @@ public class AtomPojoProvider extends AbstractConfigurableProvider
reportError(message, ex, 500);
}
- private boolean isFeedRequested(MediaType mt) {
- if ("entry".equals(mt.getParameters().get("type"))) {
+ protected boolean isFeedRequested(MediaType mt) {
+ if ("entry".equalsIgnoreCase(mt.getParameters().get("type"))) {
return false;
}
return true;
@@ -600,25 +600,29 @@ public class AtomPojoProvider extends AbstractConfigurableProvider
boolean isFeed = isFeedRequested(mt);
if (isFeed) {
- return readFromFeed(cls, mt, headers, is);
+ return readFromFeedOrEntry(cls, mt, headers, is);
} else {
AtomEntryProvider p = new AtomEntryProvider();
p.setAutodetectCharset(autodetectCharset);
Entry entry = p.readFrom(Entry.class, Entry.class,
new Annotation[]{}, mt, headers, is);
- return readFromEntry(entry, cls, mt, headers, is);
+ return readFromEntry(entry, cls);
}
}
@SuppressWarnings("unchecked")
- private Object readFromFeed(Class<Object> cls, MediaType mt,
+ private Object readFromFeedOrEntry(Class<Object> cls, MediaType mt,
MultivaluedMap<String, String> headers, InputStream is)
throws IOException {
AtomFeedProvider p = new AtomFeedProvider();
p.setAutodetectCharset(autodetectCharset);
- Feed feed = p.readFrom(Feed.class, Feed.class, new Annotation[]{}, mt, headers, is);
-
+ Object atomObject = p.readFrom(Feed.class, Feed.class, new Annotation[]{}, mt, headers, is);
+ if (atomObject instanceof Entry) {
+ return this.readFromEntry((Entry)atomObject, cls);
+ }
+
+ Feed feed = (Feed)atomObject;
AtomElementReader<?, ?> reader = getAtomReader(cls);
if (reader != null) {
return ((AtomElementReader<Feed, Object>)reader).readFrom(feed);
@@ -631,7 +635,7 @@ public class AtomPojoProvider extends AbstractConfigurableProvider
= (Class<Object>)InjectionUtils.getActualType(m.getGenericParameterTypes()[0]);
List<Object> objects = new ArrayList<Object>();
for (Entry e : feed.getEntries()) {
- objects.add(readFromEntry(e, realCls, mt, headers, is));
+ objects.add(readFromEntry(e, realCls));
}
instance = cls.newInstance();
m.invoke(instance, new Object[]{objects});
@@ -643,20 +647,22 @@ public class AtomPojoProvider extends AbstractConfigurableProvider
}
@SuppressWarnings("unchecked")
- private Object readFromEntry(Entry entry, Class<Object> cls, MediaType mt,
- MultivaluedMap<String, String> headers, InputStream is)
+ private Object readFromEntry(Entry entry, Class<Object> cls)
throws IOException {
AtomElementReader<?, ?> reader = getAtomReader(cls);
if (reader != null) {
return ((AtomElementReader<Entry, Object>)reader).readFrom(entry);
}
- try {
- Unmarshaller um =
- jaxbProvider.getJAXBContext(cls, cls).createUnmarshaller();
- return cls.cast(um.unmarshal(new StringReader(entry.getContent())));
- } catch (Exception ex) {
- reportError("Object of type " + cls.getName() + " can not be deserialized from Entry", ex, 400);
+ String entryContent = entry.getContent();
+ if (entryContent != null) {
+ try {
+ Unmarshaller um =
+ jaxbProvider.getJAXBContext(cls, cls).createUnmarshaller();
+ return cls.cast(um.unmarshal(new StringReader(entryContent)));
+ } catch (Exception ex) {
+ reportError("Object of type " + cls.getName() + " can not be deserialized from Entry", ex, 400);
+ }
}
return null;
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/73963a76/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProviderTest.java
----------------------------------------------------------------------
diff --git a/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProviderTest.java b/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProviderTest.java
index b214ae9..1d0fb79 100644
--- a/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProviderTest.java
+++ b/rt/rs/extensions/providers/src/test/java/org/apache/cxf/jaxrs/provider/atom/AtomPojoProviderTest.java
@@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.StringReader;
import java.lang.annotation.Annotation;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
@@ -31,6 +32,7 @@ import javax.xml.bind.annotation.XmlRootElement;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
+import org.apache.cxf.jaxrs.impl.MetadataMap;
import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
import org.junit.Assert;
@@ -39,25 +41,24 @@ import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
public class AtomPojoProviderTest extends Assert {
private ClassPathXmlApplicationContext ctx;
-
+
@Before
public void setUp() {
- ctx =
+ ctx =
new ClassPathXmlApplicationContext(
new String[] {"/org/apache/cxf/jaxrs/provider/atom/servers.xml"});
}
-
+
@Test
public void testWriteFeedWithBuilders() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atom");
assertNotNull(provider);
provider.setFormattedOutput(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
+
Books books = new Books();
List<Book> bs = new ArrayList<Book>();
bs.add(new Book("a"));
@@ -67,20 +68,20 @@ public class AtomPojoProviderTest extends Assert {
MediaType.valueOf("application/atom+xml"), null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Feed feed = new AtomFeedProvider().readFrom(Feed.class, null, null, null, null, bis);
- assertEquals("Books", feed.getTitle());
+ assertEquals("Books", feed.getTitle());
List<Entry> entries = feed.getEntries();
assertEquals(2, entries.size());
verifyEntry(getEntry(entries, "a"), "a");
verifyEntry(getEntry(entries, "b"), "b");
}
-
+
@Test
public void testWriteFeedWithBuildersNoJaxb() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atomNoJaxb");
assertNotNull(provider);
provider.setFormattedOutput(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
-
+
Books books = new Books();
List<Book> bs = new ArrayList<Book>();
bs.add(new Book("a"));
@@ -90,23 +91,23 @@ public class AtomPojoProviderTest extends Assert {
MediaType.valueOf("application/atom+xml"), null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Feed feed = new AtomFeedProvider().readFrom(Feed.class, null, null, null, null, bis);
- assertEquals("Books", feed.getTitle());
+ assertEquals("Books", feed.getTitle());
List<Entry> entries = feed.getEntries();
assertEquals(2, entries.size());
-
+
Entry entryA = getEntry(entries, "a");
verifyEntry(entryA, "a");
String entryAContent = entryA.getContent();
assertTrue("<a/>".equals(entryAContent) || "<a><a/>".equals(entryAContent)
|| "<a xmlns=\"\"/>".equals(entryAContent));
-
+
Entry entryB = getEntry(entries, "b");
verifyEntry(entryB, "b");
String entryBContent = entryB.getContent();
assertTrue("<b/>".equals(entryBContent) || "<b><b/>".equals(entryBContent)
|| "<b xmlns=\"\"/>".equals(entryBContent));
}
-
+
@Test
public void testWriteEntryWithBuilders() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atom2");
@@ -118,21 +119,21 @@ public class AtomPojoProviderTest extends Assert {
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
Entry entry = new AtomEntryProvider().readFrom(Entry.class, null, null, null, null, bis);
verifyEntry(entry, "a");
-
+
}
-
+
@Test
public void testReadEntryWithBuilders() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atom3");
assertNotNull(provider);
doTestReadEntry(provider);
}
-
+
@Test
public void testReadEntryWithoutBuilders() throws Exception {
doTestReadEntry(new AtomPojoProvider());
}
-
+
private void doTestReadEntry(AtomPojoProvider provider) throws Exception {
provider.setFormattedOutput(true);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
@@ -140,19 +141,38 @@ public class AtomPojoProviderTest extends Assert {
provider.writeTo(new Book("a"), Book.class, Book.class, new Annotation[]{}, mt, null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
@SuppressWarnings({"unchecked", "rawtypes" })
- Book book = (Book)provider.readFrom((Class)Book.class, Book.class,
+ Book book = (Book)provider.readFrom((Class)Book.class, Book.class,
+ new Annotation[]{}, mt, null, bis);
+ assertEquals("a", book.getName());
+ }
+ @Test
+ public void testReadEntryNoBuilders2() throws Exception {
+ final String entry =
+ "<!DOCTYPE entry SYSTEM \"entry://entry\"><entry xmlns=\"http://www.w3.org/2005/Atom\">"
+ + "<title type=\"text\">a</title>"
+ + "<content type=\"application/xml\">"
+ + "<book xmlns=\"\">"
+ + "<name>a</name>"
+ + "</book>"
+ + "</content>"
+ + "</entry>";
+ AtomPojoProvider provider = new AtomPojoProvider();
+ ByteArrayInputStream bis = new ByteArrayInputStream(entry.getBytes());
+ MediaType mt = MediaType.valueOf("application/atom+xml;type=entry");
+ @SuppressWarnings({"unchecked", "rawtypes" })
+ Book book = (Book)provider.readFrom((Class)Book.class, Book.class,
new Annotation[]{}, mt, null, bis);
assertEquals("a", book.getName());
}
-
-
+
+
@Test
public void testReadFeedWithBuilders() throws Exception {
AtomPojoProvider provider = (AtomPojoProvider)ctx.getBean("atom4");
assertNotNull(provider);
doTestReadFeed(provider);
}
-
+
@Test
public void testReadFeedWithoutBuilders() throws Exception {
AtomPojoProvider provider = new AtomPojoProvider();
@@ -170,14 +190,98 @@ public class AtomPojoProviderTest extends Assert {
provider.writeTo(books, Books.class, Books.class, new Annotation[]{}, mt, null, bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
@SuppressWarnings({"unchecked", "rawtypes" })
- Books books2 = (Books)provider.readFrom((Class)Books.class, Books.class,
+ Books books2 = (Books)provider.readFrom((Class)Books.class, Books.class,
new Annotation[]{}, mt, null, bis);
List<Book> list = books2.getBooks();
assertEquals(2, list.size());
assertTrue("a".equals(list.get(0).getName()) || "a".equals(list.get(1).getName()));
- assertTrue("b".equals(list.get(0).getName()) || "b".equals(list.get(1).getName()));
+ assertTrue("b".equals(list.get(0).getName()) || "b".equals(list.get(1).getName()));
+ }
+
+ @Test
+ public void testReadFeedWithoutBuilders2() throws Exception {
+ AtomPojoProvider provider = new AtomPojoProvider();
+ final String feed =
+ "<!DOCTYPE feed SYSTEM \"feed://feed\"><feed xmlns=\"http://www.w3.org/2005/Atom\">"
+ + "<entry><content type=\"application/xml\"><book xmlns=\"\"><name>a</name></book></content></entry>"
+ + "<entry><content type=\"application/xml\"><book xmlns=\"\"><name>b</name></book></content></entry>"
+ + "</feed>";
+ MediaType mt = MediaType.valueOf("application/atom+xml;type=feed");
+ ByteArrayInputStream bis = new ByteArrayInputStream(feed.getBytes());
+ @SuppressWarnings({"unchecked", "rawtypes" })
+ Books books2 = (Books)provider.readFrom((Class)Books.class, Books.class,
+ new Annotation[]{}, mt, null, bis);
+ List<Book> list = books2.getBooks();
+ assertEquals(2, list.size());
+ assertTrue("a".equals(list.get(0).getName()) || "a".equals(list.get(1).getName()));
+ assertTrue("b".equals(list.get(0).getName()) || "b".equals(list.get(1).getName()));
+ }
+
+ @Test
+ public void testReadEntryNoContent() throws Exception {
+ /** A sample entry without content. */
+ final String entryNoContent =
+ "<?xml version='1.0' encoding='UTF-8'?>\n"
+ + "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ + " <id>84297856</id>\n"
+ + "</entry>";
+
+ AtomPojoProvider atomPojoProvider = new AtomPojoProvider();
+ @SuppressWarnings({
+ "rawtypes", "unchecked"
+ })
+ JaxbDataType type = (JaxbDataType)atomPojoProvider.readFrom((Class)JaxbDataType.class,
+ JaxbDataType.class,
+ new Annotation[0],
+ MediaType.valueOf("application/atom+xml;type=entry"),
+ new MetadataMap<String, String>(),
+ new ByteArrayInputStream(entryNoContent.getBytes(Charset.forName("UTF-8"))));
+ assertNull(type);
+ }
+
+ @Test
+ public void testReadEntryWithUpperCaseTypeParam() throws Exception {
+ doReadEntryWithContent("application/atom+xml;type=ENTRY");
+ }
+
+ @Test
+ public void testReadEntryNoTypeParam() throws Exception {
+ doReadEntryWithContent("application/atom+xml");
}
-
+
+ private void doReadEntryWithContent(String mediaType) throws Exception {
+ final String entryWithContent =
+ "<?xml version='1.0' encoding='UTF-8'?>\n"
+ + "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ + " <id>84297856</id>\n"
+ + " <content type=\"application/xml\">\n"
+ + " <jaxbDataType xmlns=\"\">\n"
+ + " </jaxbDataType>\n"
+ + " </content>\n"
+ + "</entry>";
+
+ AtomPojoProvider atomPojoProvider = new AtomPojoProvider();
+ @SuppressWarnings({
+ "rawtypes", "unchecked"
+ })
+ JaxbDataType type = (JaxbDataType)atomPojoProvider.readFrom((Class)JaxbDataType.class,
+ JaxbDataType.class,
+ new Annotation[0],
+ MediaType.valueOf(mediaType),
+ new MetadataMap<String, String>(),
+ new ByteArrayInputStream(entryWithContent.getBytes(Charset.forName("UTF-8"))));
+ assertNotNull(type);
+ }
+
+ /**
+ * A sample JAXB data-type to read data into.
+ */
+ @XmlRootElement
+ public static class JaxbDataType {
+ // no data
+ }
+
+
private Entry getEntry(List<Entry> entries, String title) {
for (Entry e : entries) {
if (title.equals(e.getTitle())) {
@@ -186,35 +290,35 @@ public class AtomPojoProviderTest extends Assert {
}
return null;
}
-
+
private void verifyEntry(Entry e, String title) {
assertNotNull(e);
assertEquals(title, e.getTitle());
}
-
+
public static class CustomFeedWriter implements AtomElementWriter<Feed, Books> {
public void writeTo(Feed feed, Books pojoFeed) {
feed.setTitle("Books");
}
-
+
}
-
+
public static class CustomEntryWriter implements AtomElementWriter<Entry, Book> {
public void writeTo(Entry entry, Book pojoEntry) {
entry.setTitle(pojoEntry.getName());
}
-
+
}
-
+
public static class CustomEntryReader implements AtomElementReader<Entry, Book> {
public Book readFrom(Entry element) {
try {
String s = element.getContent();
-
- Unmarshaller um =
+
+ Unmarshaller um =
new JAXBElementProvider<Book>().getJAXBContext(Book.class, Book.class)
.createUnmarshaller();
return (Book)um.unmarshal(new StringReader(s));
@@ -223,9 +327,9 @@ public class AtomPojoProviderTest extends Assert {
}
return null;
}
-
+
}
-
+
public static class CustomFeedReader implements AtomElementReader<Feed, Books> {
public Books readFrom(Feed element) {
@@ -238,36 +342,36 @@ public class AtomPojoProviderTest extends Assert {
books.setBooks(list);
return books;
}
-
+
}
-
+
public static class CustomFeedBuilder extends AbstractFeedBuilder<Books> {
@Override
public String getBaseUri(Books books) {
return "http://books";
}
}
-
+
public static class CustomEntryBuilder extends AbstractEntryBuilder<Book> {
@Override
public String getBaseUri(Book books) {
return "http://book";
}
}
-
-
+
+
@XmlRootElement
public static class Book {
private String name = "Book";
public Book() {
-
+
}
-
+
public Book(String name) {
this.name = name;
}
-
+
public void setName(String name) {
this.name = name;
}
@@ -275,26 +379,26 @@ public class AtomPojoProviderTest extends Assert {
public String getName() {
return name;
}
-
+
public String getXMLContent() {
return "<" + name + "/>";
}
-
+
}
-
+
@XmlRootElement
public static class Books {
-
+
private List<Book> books;
-
+
public Books() {
-
+
}
-
+
public List<Book> getBooks() {
return books;
}
-
+
public void setBooks(List<Book> list) {
books = list;
}