TriXParserTest.java
/*******************************************************************************
* Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.rio.trix;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Locale;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
import org.eclipse.rdf4j.rio.RDFParseException;
import org.eclipse.rdf4j.rio.RDFParser;
import org.eclipse.rdf4j.rio.helpers.ParseErrorCollector;
import org.eclipse.rdf4j.rio.helpers.StatementCollector;
import org.eclipse.rdf4j.rio.helpers.XMLParserSettings;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class TriXParserTest {
private ValueFactory vf;
private RDFParser parser;
private StatementCollector sc;
private ParseErrorCollector el;
private Locale platformLocale;
@BeforeEach
public void setUp() {
platformLocale = Locale.getDefault();
Locale.setDefault(Locale.ENGLISH);
vf = SimpleValueFactory.getInstance();
parser = new TriXParser();
sc = new StatementCollector();
parser.setRDFHandler(sc);
el = new ParseErrorCollector();
parser.setParseErrorListener(el);
}
@AfterEach
public void tearDown() {
Locale.setDefault(platformLocale);
}
@Test
public void testFatalErrorDoctypeDecl() throws Exception {
// configure parser to disallow doctype declarations
parser.getParserConfig().set(XMLParserSettings.DISALLOW_DOCTYPE_DECL, true);
try (final InputStream in = this.getClass()
.getResourceAsStream("/org/eclipse/rdf4j/rio/trix/trix-xxe-external-entity.trix")) {
parser.parse(in, "");
} catch (RDFParseException e) {
assertEquals(
"DOCTYPE is disallowed when the feature \"http://apache.org/xml/features/disallow-doctype-decl\" set to true. [line 1, column 10]",
e.getMessage());
}
assertEquals(0, el.getWarnings().size());
assertEquals(0, el.getErrors().size());
assertEquals(1, el.getFatalErrors().size());
assertEquals(
"[Rio fatal] DOCTYPE is disallowed when the feature \"http://apache.org/xml/features/disallow-doctype-decl\" set to true. (1, 10)",
el.getFatalErrors().get(0));
}
@Test
public void testIgnoreExternalDTD_default() throws Exception {
try (final InputStream in = this.getClass()
.getResourceAsStream("/org/eclipse/rdf4j/rio/trix/trix-xxe-external-dtd.trix")) {
parser.parse(in, "");
} catch (FileNotFoundException e) {
fail("parser tried to read external DTD");
}
assertEquals(0, el.getWarnings().size());
assertEquals(0, el.getErrors().size());
assertEquals(0, el.getFatalErrors().size());
assertThat(sc.getStatements().size()).isEqualTo(1);
Statement st = sc.getStatements().iterator().next();
// literal value should be empty string as it should not have processed the external entity
assertThat(st.getObject().stringValue()).isEqualTo("");
}
@Test
public void testLoadExternalDTD_configured() throws Exception {
parser.getParserConfig().set(XMLParserSettings.LOAD_EXTERNAL_DTD, true);
try (final InputStream in = this.getClass()
.getResourceAsStream("/org/eclipse/rdf4j/rio/trix/trix-xxe-external-dtd.trix")) {
assertThatExceptionOfType(FileNotFoundException.class)
.isThrownBy(() -> parser.parse(in, ""))
.withMessageMatching(".*non-existent\\.dtd.*");
}
}
@Test
public void testIgnoreExternalGeneralEntity() throws Exception {
try (final InputStream in = this.getClass()
.getResourceAsStream("/org/eclipse/rdf4j/rio/trix/trix-xxe-external-entity.trix")) {
parser.parse(in, "");
} catch (FileNotFoundException e) {
fail("parser tried to read external file from external general entity");
}
assertEquals(0, el.getWarnings().size());
assertEquals(0, el.getErrors().size());
assertEquals(0, el.getFatalErrors().size());
assertThat(sc.getStatements().size()).isEqualTo(1);
Statement st = sc.getStatements().iterator().next();
// literal value should be empty string as it should not have processed the external entity
assertThat(st.getObject().stringValue()).isEqualTo("");
}
@Test
public void testIgnoreExternalParameterEntity() throws Exception {
// configure parser to allow doctype declarations
parser.getParserConfig().set(XMLParserSettings.DISALLOW_DOCTYPE_DECL, false);
try (final InputStream in = this.getClass()
.getResourceAsStream("/org/eclipse/rdf4j/rio/trix/trix-xxe-external-param-entity.trix")) {
parser.parse(in, "");
} catch (FileNotFoundException e) {
fail("parser tried to read external file from external parameter entity");
}
assertEquals(0, el.getWarnings().size());
assertEquals(0, el.getErrors().size());
assertEquals(0, el.getFatalErrors().size());
}
@Test
public void testFatalErrorPrologContent() throws Exception {
try (final InputStream in = this.getClass()
.getResourceAsStream("/org/eclipse/rdf4j/rio/trix/not-a-trix-file.trix")) {
parser.parse(in, "");
} catch (RDFParseException e) {
assertEquals("Content is not allowed in prolog. [line 1, column 1]", e.getMessage());
}
assertEquals(0, el.getWarnings().size());
assertEquals(0, el.getErrors().size());
assertEquals(1, el.getFatalErrors().size());
assertEquals("[Rio fatal] Content is not allowed in prolog. (1, 1)", el.getFatalErrors().get(0));
}
}