Skip to content

Commit

Permalink
Fixed issue where if the main resource accessor doesn't find the XSD …
Browse files Browse the repository at this point in the history
…file but it's found by the fallback one, LiquibaseEntityResolver always loads it over the network
  • Loading branch information
nvoxland committed May 5, 2022
1 parent 803d3d5 commit 5fb7a2d
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,20 @@ public InputSource resolveEntity(String name, String publicId, String baseURI, S
if (streams.isEmpty()) {
streams = getFallbackResourceAccessor().openStreams(null, path);

if (streams.isEmpty() && GlobalConfiguration.SECURE_PARSING.getCurrentValue()) {
String errorMessage = "Unable to resolve xml entity " + systemId + " locally: " +
GlobalConfiguration.SECURE_PARSING.getKey() + " is set to 'true' which does not allow remote lookups. " +
"Set it to 'false' to allow remote lookups of xsd files.";
throw new XSDLookUpException(errorMessage);
} else {
log.fine("Unable to resolve XML entity locally. Will load from network.");
return null;
if (streams.isEmpty()) {
if (GlobalConfiguration.SECURE_PARSING.getCurrentValue()) {
String errorMessage = "Unable to resolve xml entity " + systemId + " locally: " +
GlobalConfiguration.SECURE_PARSING.getKey() + " is set to 'true' which does not allow remote lookups. " +
"Set it to 'false' to allow remote lookups of xsd files.";
throw new XSDLookUpException(errorMessage);
} else {
log.fine("Unable to resolve XML entity locally. Will load from network.");
return null;
}
}
} else if (streams.size() == 1) {
}

if (streams.size() == 1) {
log.fine("Found XML entity at " + streams.getURIs().get(0));
} else if (streams.size() > 1) {
log.warning("Found " + streams.size() + " copies of " + systemId + ". Using " + streams.getURIs().get(0));
Expand Down Expand Up @@ -84,7 +88,7 @@ public InputSource getExternalSubset(String name, String baseURI) throws SAXExce

@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
Scope.getCurrentScope().getLog(getClass()).warning("Current XML parsers seems to not support EntityResolver2. External entities won't be correctly loaded");
Scope.getCurrentScope().getLog(getClass()).warning("The current XML parser does not seems to not support EntityResolver2. External entities may not be correctly loaded");
return resolveEntity(null, publicId, null, systemId);
}
}
Original file line number Diff line number Diff line change
@@ -1,104 +1,76 @@
package liquibase.parser.core.xml

import org.junit.Test;

import liquibase.GlobalConfiguration
import liquibase.Scope
import liquibase.resource.FileSystemResourceAccessor
import spock.lang.Specification
import spock.lang.Unroll

class LiquibaseEntityResolverTest extends Specification {

@Unroll
def "resolveEntity finds packaged files correctly"() {
expect:
new LiquibaseEntityResolver().resolveEntity(null, null, null, systemId) != null

where:
systemId << [
"http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd",
"https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd",
"http://www.liquibase.org/xml/ns/migrator/dbchangelog-3.1.xsd",
"http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-next.xsd",
"http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd",
"META-INF/services/liquibase.change.Change"
]
}

@Unroll
def "resolveEntity finds packaged files correctly even if the configured resourceAccessor doesn't have it"() {
expect:
Scope.child([(Scope.Attr.resourceAccessor.name()): new FileSystemResourceAccessor(new File("."))], { ->
new LiquibaseEntityResolver().resolveEntity(null, null, null, systemId) != null
} as Scope.ScopedRunnerWithReturn) != null

where:
systemId << [
"http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd",
"https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd",
]
}

@Unroll
def "resolveEntity returns null for non-packaged files"() {
expect:
Scope.child(GlobalConfiguration.SECURE_PARSING.key, false, { ->
new LiquibaseEntityResolver().resolveEntity(null, null, null, systemId) == null
}) == null

when:
Scope.child(GlobalConfiguration.SECURE_PARSING.key, true, { ->
new LiquibaseEntityResolver().resolveEntity(null, null, null, systemId) == null
})

then:
def e = thrown(XSDLookUpException)
e.message.startsWith("Unable to resolve xml entity")


where:
systemId << [
"http://www.liquibase.org/xml/ns/dbchangelog/invalid.xsd",
"http://www.example.com/xml/ns/dbchangelog/dbchangelog-3.1.xsd",
"http://www.example.com/random/file.txt",
]
}

def "null systemId returns null"() {
expect:
new LiquibaseEntityResolver().resolveEntity("passed publicId", null) == null
new LiquibaseEntityResolver().resolveEntity("passed name", "passed publicId", "passed baseURI", null) == null
}

//@RunWith(PowerMockRunner.class)
//@PrepareForTest({ LiquibaseEntityResolver.class, StreamUtil.class })
public class LiquibaseEntityResolverTest extends Specification {
//
// private static final String SYSTEM_ID = "http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd";
//
// private static final String SYSTEM_ID_WITH_MIGRATOR_PATH = "http://www.liquibase.org/xml/ns/migrator/dbchangelog-1.0.xsd";
// private static final String SYSTEM_ID_FROM_MIGRATOR_PATH = "http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.0.xsd";
//
// private static final String PUBLIC_ID = "publicId";
// private static final String NAME = "name";
//
// private static final String BASE_URI = "baseUri";
// private static final String BASE_PATH = "basePath";
// private static final String FILE_SYSTEM_ID = "fileSystemId";
// private static final String PATH_AND_SYSTEM_ID = FilenameUtils.concat(BASE_PATH, FILE_SYSTEM_ID);
//
// private LiquibaseEntityResolver liquibaseEntityResolver;
//
// @Mock
// private LiquibaseSchemaResolver liquibaseSchemaResolver;
//
// @Mock
// private ResourceAccessor resourceAccessor;
//
// @Mock
// private InputSource inputSource;
//
// @Mock
// private XMLChangeLogSAXParser parser;
//
// @Mock
// private InputStream inputStream;
//
// @Mock
// private LiquibaseSerializer serializer;
//
// @Before
// public void setUp() throws Exception {
// PowerMockito.mockStatic(StreamUtil.class);
//
// PowerMockito.whenNew(LiquibaseSchemaResolver.class).withArguments(SYSTEM_ID, PUBLIC_ID, resourceAccessor).thenReturn(liquibaseSchemaResolver);
//
// when(liquibaseSchemaResolver.resolve(parser)).thenReturn(inputSource);
// when(liquibaseSchemaResolver.resolve(serializer)).thenReturn(inputSource);
//
// liquibaseEntityResolver = new LiquibaseEntityResolver(parser);
// liquibaseEntityResolver.useResoureAccessor(resourceAccessor, BASE_PATH);
// }
//
// @Test
// public void shouldReturnNullSystemIdIsNull() throws Exception {
// InputSource result = liquibaseEntityResolver.resolveEntity(NAME, PUBLIC_ID, BASE_URI, null);
//
// assertThat(result).isNull();
// }
//
// @Test
// public void systemIdStartingWithMigratorShouldBeReplacedByDbChangelog() throws Exception {
// PowerMockito.whenNew(LiquibaseSchemaResolver.class).withArguments(SYSTEM_ID_FROM_MIGRATOR_PATH, PUBLIC_ID, resourceAccessor).thenReturn(liquibaseSchemaResolver);
//
// InputSource result = liquibaseEntityResolver.resolveEntity(NAME, PUBLIC_ID, BASE_URI, SYSTEM_ID_WITH_MIGRATOR_PATH);
//
// assertThat(result).isSameAs(inputSource);
// }
//
// @Test
// public void shouldReturnSchemaResolverResultWhenSystemIdIsValidXsd() throws IOException, SAXException {
// InputSource result = liquibaseEntityResolver.resolveEntity(NAME, PUBLIC_ID, BASE_URI, SYSTEM_ID);
//
// assertThat(result).isSameAs(inputSource);
// }
//
// @Test
// public void shouldReturnSchemaResolverResultWhenSystemIdIsValidXsdAndSerializerIsNotNull() throws IOException, SAXException {
// liquibaseEntityResolver = new LiquibaseEntityResolver(serializer);
// liquibaseEntityResolver.useResoureAccessor(resourceAccessor, BASE_PATH);
//
// InputSource result = liquibaseEntityResolver.resolveEntity(NAME, PUBLIC_ID, BASE_URI, SYSTEM_ID);
//
// assertThat(result).isSameAs(inputSource);
// }
//
//
// @Test
// public void resolveEntityWithOnlyPublicIdAndSystemIdDelegatesToSchemResolver() throws IOException, SAXException {
// InputSource result = liquibaseEntityResolver.resolveEntity(PUBLIC_ID, SYSTEM_ID);
//
// assertThat(result).isSameAs(inputSource);
// }
//
// @Test
// public void getExternalSubsetShouldReturnNull() throws IOException, SAXException {
// InputSource externalSubset = liquibaseEntityResolver.getExternalSubset(NAME, BASE_URI);
//
// assertThat(externalSubset).isNull();
// }
def "getExternalSubset returns null"() {
expect:
assert new LiquibaseEntityResolver().getExternalSubset("pased name", "passed baseURI") == null
}
}

0 comments on commit 5fb7a2d

Please sign in to comment.