Skip to content

Commit

Permalink
Merge pull request #172 from defold/issue-171-custom-include-path
Browse files Browse the repository at this point in the history
Issue 171: Add support for custom include path
  • Loading branch information
JCash authored Sep 2, 2020
2 parents ec04ae5 + dab0be8 commit 908b587
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 14 deletions.
18 changes: 14 additions & 4 deletions server/src/main/java/com/defold/extender/Extender.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ private class ProGuardContext {
this.manifestValidator = new ExtensionManifestValidator(new WhitelistConfig(), this.platformConfig.allowedFlags, allowedSymbols);

// Make sure the user hasn't input anything invalid in the manifest
this.manifestValidator.validate(this.appManifestPath, appManifestContext);
this.manifestValidator.validate(this.appManifestPath, this.uploadDirectory, appManifestContext);

// Collect extension directories (used by both buildEngine and buildClassesDex)
this.manifests = allFiles.stream().filter(f -> f.getName().equals("ext.manifest")).collect(Collectors.toList());
Expand Down Expand Up @@ -445,8 +445,18 @@ else if(f.getName().endsWith(".aar")) {

private File compileFile(int index, File extDir, File src, Map<String, Object> manifestContext, List<String> commands) throws IOException, InterruptedException, ExtenderException {
List<String> includes = new ArrayList<>();
includes.add( ExtenderUtil.getRelativePath(jobDirectory, new File(extDir, "include") ) );
File extIncludeDir = new File(extDir, "include");
includes.add( ExtenderUtil.getRelativePath(jobDirectory, extIncludeDir ) );
includes.add( ExtenderUtil.getRelativePath(jobDirectory, uploadDirectory) );

// Add the other extensions include folders
for (File otherExtDir : this.getExtensionFolders()) {
File otherIncludeDir = new File(otherExtDir, "include");
if (extIncludeDir.equals(otherIncludeDir))
continue;
includes.add( ExtenderUtil.getRelativePath(jobDirectory, otherIncludeDir ) );
}

File o = new File(buildDirectory, String.format("%s_%d.o", src.getName(), index));

List<String> frameworks = getFrameworks(extDir);
Expand Down Expand Up @@ -987,7 +997,7 @@ private Map<String,ProGuardContext> buildJava(File rJar) throws ExtenderExceptio
manifestContext = getManifestContext(platform, config, manifestConfig);
}

this.manifestValidator.validate(manifestConfig.name, manifestContext);
this.manifestValidator.validate(manifestConfig.name, manifest.getParentFile(), manifestContext);

manifestConfigs.put(manifestConfig.name, manifestContext);

Expand Down Expand Up @@ -1287,7 +1297,7 @@ private void loadManifests() throws IOException, ExtenderException {
}

String relativePath = ExtenderUtil.getRelativePath(this.uploadDirectory, manifest);
this.manifestValidator.validate(relativePath, manifestContext);
this.manifestValidator.validate(relativePath, manifest.getParentFile(), manifestContext);

// Apply any global settings to the context
manifestContext.put("extension_name", manifestConfig.name);
Expand Down
6 changes: 6 additions & 0 deletions server/src/main/java/com/defold/extender/ExtenderUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.nio.file.Path;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
Expand Down Expand Up @@ -379,4 +380,9 @@ public static File getAndroidResourceFolder(File dir) {
return null;
}

public static boolean isChild(File parent, File child) {
Path parentPath = parent.toPath().normalize().toAbsolutePath();
Path childPath = child.toPath().normalize().toAbsolutePath();
return childPath.startsWith(parentPath);
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package com.defold.extender;

import java.io.File;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class ExtensionManifestValidator {
private static final Logger LOGGER = LoggerFactory.getLogger(ExtensionManifestValidator.class);

private final List<Pattern> allowedLibs = new ArrayList<>();
private final List<Pattern> allowedFlags = new ArrayList<>();
Expand All @@ -27,7 +32,28 @@ private static boolean isListOfStrings(List<Object> list) {
return list != null && list.stream().allMatch(o -> o instanceof String);
}

void validate(String extensionName, Map<String, Object> context) throws ExtenderException {
private void validateIncludePaths(String extensionName, File extensionFolder, List<String> includes) throws ExtenderException {
for (String include : includes) {
String[] tokens = include.split("/");
for (int i = 0; i < tokens.length; ++i)
{
String[] subtokens = Arrays.copyOfRange(tokens, 0, i);
String s = String.join("/", subtokens);
File f = new File(extensionFolder, s);

if (!ExtenderUtil.isChild(extensionFolder, f))
{
throw new ExtenderException(String.format("Error in '%s': The include '%s' path must be relative subdirectory to the extension folder '%s'", extensionName, include, extensionFolder));
}

if (!f.exists()) {
LOGGER.warn("The include path '%s' does not exist:", f);
}
}
}
}

void validate(String extensionName, File extensionFolder, Map<String, Object> context) throws ExtenderException {
Set<String> keys = context.keySet();
for (String k : keys) {
Object v = context.get(k);
Expand Down Expand Up @@ -64,6 +90,14 @@ void validate(String extensionName, Map<String, Object> context) throws Extender
type = "symbol";
break;

case "includes":
if (!(v instanceof List)) {
throw new ExtenderException(String.format("Error in '%s': The 'includes' must be a list of strings. Got %s: %s (type %s)", extensionName, k, v.toString(), v.getClass().getCanonicalName()));
}

validateIncludePaths(extensionName, extensionFolder, (List<String>) v);
continue;

case "excludeLibs":
case "excludeJars":
case "excludeJsLibs":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ private File getRelative(File dir, File path) {

@Test
public void testAndroidAssetFolders() throws IOException, InterruptedException, ExtenderException {
System.out.printf("MAWE: testAndroidAssetFolders\n");
File d;
d = new File(uploadDir, "extension1/res/android/res/com.foo.name/res/values"); d.mkdirs(); assertTrue(d.exists());
d = new File(uploadDir, "extension2/res/android/res/com.foo.name/values"); d.mkdirs(); assertTrue(d.exists());
Expand All @@ -79,4 +78,12 @@ public void testAndroidAssetFolders() throws IOException, InterruptedException,
d = ExtenderUtil.getAndroidResourceFolder(new File(uploadDir, "extension3/res/android/res/values"));
assertNull(d);
}

@Test
public void testChild() throws IOException, InterruptedException, ExtenderException {
File parent = new File("upload/extension1");
assertEquals( ExtenderUtil.isChild(parent, new File("upload/extension1")), true );
assertEquals( ExtenderUtil.isChild(parent, new File("upload/extension1/file")), true );
assertEquals( ExtenderUtil.isChild(parent, new File("upload")), false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,23 @@ public void testWhitelistCheckContext() throws ExtenderException, IOException {
Map<String, Object> context = new HashMap<>();

// LIBS
File extensionFolder = new File("ext-folder");

stringValues.clear();
context.clear();
stringValues.add("AVFAudio");
stringValues.add("QuickTime");
context.put("libs", stringValues);

validator.validate("test_extension", context);
validator.validate("test_extension", extensionFolder, context);


stringValues.clear();
context.clear();
stringValues.add("c++");
context.put("libs", stringValues);

validator.validate("test_extension", context);
validator.validate("test_extension", extensionFolder, context);


stringValues.clear();
Expand All @@ -86,7 +87,7 @@ public void testWhitelistCheckContext() throws ExtenderException, IOException {
boolean thrown;
try {
thrown = false;
validator.validate("test_extension", context);
validator.validate("test_extension", extensionFolder, context);
} catch (ExtenderException e) {
thrown = true;
}
Expand All @@ -101,7 +102,7 @@ public void testWhitelistCheckContext() throws ExtenderException, IOException {
stringValues.add("-Weverything");
context.put("flags", stringValues);

validator.validate("test_extension", context);
validator.validate("test_extension", extensionFolder, context);


stringValues.clear();
Expand All @@ -111,7 +112,7 @@ public void testWhitelistCheckContext() throws ExtenderException, IOException {
stringValues.add("-std=c++14");
context.put("flags", stringValues);

validator.validate("test_extension", context);
validator.validate("test_extension", extensionFolder, context);


stringValues.clear();
Expand All @@ -122,7 +123,7 @@ public void testWhitelistCheckContext() throws ExtenderException, IOException {

try {
thrown = false;
validator.validate("test_extension", context);
validator.validate("test_extension", extensionFolder, context);
} catch (ExtenderException e) {
if (e.toString().contains("rm -rf")) {
thrown = true;
Expand All @@ -146,9 +147,10 @@ public void testAllowedLibs() throws ExtenderException {
l.add("z");
context.put("libs", l);

File extensionFolder = new File("ext-folder");
boolean thrown = false;
try {
validator.validate("testExtension", context);
validator.validate("testExtension", extensionFolder, context);
} catch (ExtenderException e) {
thrown = true;
System.out.println(e.toString());
Expand All @@ -159,7 +161,7 @@ public void testAllowedLibs() throws ExtenderException {
l.add("../libfoobar.a");
context.put("libs", l);
try {
validator.validate("testExtension", context);
validator.validate("testExtension", extensionFolder, context);
} catch (ExtenderException e) {
System.out.println(e.toString());
if (e.toString().contains("Invalid")) { // expected error
Expand Down

0 comments on commit 908b587

Please sign in to comment.