Skip to content

Commit ac6767d

Browse files
committed
Merge remote-tracking branch 'origin/master' into vmutafov/master-into-release
2 parents 4ecdc3c + 0c81921 commit ac6767d

File tree

129 files changed

+58805
-59927
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

129 files changed

+58805
-59927
lines changed

CHANGELOG.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
6.4.0
2+
==
3+
4+
## What's New
5+
6+
- [[FR] Customize metadata generation to avoid adding unnecessary unused JS wrappers (#1485)](https://github.com/NativeScript/android-runtime/issues/1485)
7+
- [Upgrade v8 to 7.9.317.31 (#1526)](https://github.com/NativeScript/android-runtime/issues/1555)
8+
- [Upgrade android gradle plugin to the latest 3.5.3 version (#1564)](https://github.com/NativeScript/android-runtime/issues/1564)
9+
10+
## Bug Fixes
11+
12+
- [WebAssembly won't initialize without the debugger (#1558)](https://github.com/NativeScript/android-runtime/issues/1558)
13+
- [Clean up allocations from finalized object links (#1566)](https://github.com/NativeScript/android-runtime/pull/1566)
14+
- [Fix Kotlin Object issue (#1562)](https://github.com/NativeScript/android-runtime/pull/1562)
15+
116
6.3.1
217
==
318

@@ -33,7 +48,7 @@
3348
- [Upgrade android gradle plugin to the latest 3.5.1 version (#1502)](https://github.com/NativeScript/android-runtime/issues/1502)
3449
- [support snapshot libs out of the box (#1496)](https://github.com/NativeScript/android-runtime/pull/1496)
3550
- [Upgrade v8 to 7.7.299.11 (#1478)](https://github.com/NativeScript/android-runtime/issues/1478)
36-
51+
3752
## Bug Fixes
3853
- [Console.log in worker makes chrome debugging crash (#1511)](https://github.com/NativeScript/android-runtime/issues/1511)
3954
- [fix searching for merge assets folder on windows (#1503)](https://github.com/NativeScript/android-runtime/pull/1503)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"v8Version": "7.8.279.19",
2+
"v8Version": "7.9.317.31",
33
"ndkRevision": "20.0.5594570",
44
"mksnapshotParams": "--profile_deserialization --turbo_instruction_scheduling --target_os=android --no-native-code-counters"
55
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "tns-android",
33
"description": "NativeScript Runtime for Android",
4-
"version": "6.3.1",
4+
"version": "6.4.0",
55
"repository": {
66
"type": "git",
77
"url": "https://github.com/NativeScript/android-runtime.git"
@@ -11,7 +11,7 @@
1111
],
1212
"gradle": {
1313
"version": "5.4.1",
14-
"android": "3.5.1"
14+
"android": "3.5.3"
1515
},
1616
"android_ndk_version": "20"
1717
}

test-app/app/build.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,11 @@ task collectAllJars {
734734
}
735735
}
736736

737+
task copyMetadataFilters(type: Copy) {
738+
from "$rootDir/whitelist.mdg", "$rootDir/blacklist.mdg"
739+
into "$BUILD_TOOLS_PATH"
740+
}
741+
737742
task copyMetadata {
738743
doLast {
739744
copy {
@@ -748,6 +753,8 @@ task buildMetadata(type: BuildToolTask) {
748753
dependsOn ':android-metadata-generator:jar'
749754
}
750755

756+
dependsOn copyMetadataFilters
757+
751758
// As some external gradle plugins can reorder the execution order of the tasks it may happen that buildMetadata is executed after merge{Debug/Release}Assets
752759
// in that case the metadata won't be included in the result apk and it will crash, so to avoid this we are adding the copyMetadata task which will manually copy
753760
// the metadata files in the merge assets folder and they will be added to the result apk
@@ -924,6 +931,8 @@ task cleanSbg(type: Delete) {
924931

925932
task cleanMdg(type: Delete) {
926933
delete "$BUILD_TOOLS_PATH/$MDG_OUTPUT_DIR",
934+
"$BUILD_TOOLS_PATH/whitelist.mdg",
935+
"$BUILD_TOOLS_PATH/blacklist.mdg",
927936
"$BUILD_TOOLS_PATH/$MDG_JAVA_DEPENDENCIES",
928937
"$METADATA_OUT_PATH"
929938
}

test-app/app/src/main/assets/app/mainpage.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ shared.runRequireTests();
2020
shared.runWeakRefTests();
2121
shared.runRuntimeTests();
2222
shared.runWorkerTests();
23+
require("./tests/testWebAssembly");
2324
require("./tests/testInterfaceDefaultMethods");
2425
require("./tests/testInterfaceStaticMethods");
2526
require("./tests/testMetadata");

test-app/app/src/main/assets/app/tests/kotlin/objects/testObjectsSupport.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ describe("Tests Kotlin objects support", function () {
22
it("Test Kotlin object instances should be the same reference", function () {
33
var kotlinClass = com.tns.tests.kotlin.objects.KotlinSingleton.INSTANCE;
44
var kotlinClass2 = com.tns.tests.kotlin.objects.KotlinSingleton.INSTANCE;
5+
6+
expect(kotlinClass).not.toBe(null);
7+
expect(kotlinClass).not.toBe(undefined);
8+
expect(kotlinClass2).not.toBe(null);
9+
expect(kotlinClass2).not.toBe(undefined);
10+
511
expect(com.tns.EqualityComparator.areReferencesEqual(kotlinClass, kotlinClass2)).toBe(true);
612
});
713
});
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
describe("Test WebAssembly ", () => {
2+
// https://wasdk.github.io/WasmFiddle/?15acre
3+
//
4+
// #include <stdio.h>
5+
// #include <sys/uio.h>
6+
//
7+
// #define WASM_EXPORT __attribute__((visibility("default")))
8+
//
9+
// extern double logarithm(double value);
10+
//
11+
// WASM_EXPORT int log(double value) {
12+
// return logarithm(value);
13+
// }
14+
let wasmCode = new Uint8Array([
15+
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x8b, 0x80, 0x80, 0x80, 0x00, 0x02,
16+
0x60, 0x01, 0x7c, 0x01, 0x7c, 0x60, 0x01, 0x7c, 0x01, 0x7f, 0x02, 0x91, 0x80, 0x80, 0x80,
17+
0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x09, 0x6c, 0x6f, 0x67, 0x61, 0x72, 0x69, 0x74, 0x68,
18+
0x6d, 0x00, 0x00, 0x03, 0x82, 0x80, 0x80, 0x80, 0x00, 0x01, 0x01, 0x04, 0x84, 0x80, 0x80,
19+
0x80, 0x00, 0x01, 0x70, 0x00, 0x00, 0x05, 0x83, 0x80, 0x80, 0x80, 0x00, 0x01, 0x00, 0x01,
20+
0x06, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x07, 0x90, 0x80, 0x80, 0x80, 0x00, 0x02, 0x06,
21+
0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x03, 0x6c, 0x6f, 0x67, 0x00, 0x01, 0x0a,
22+
0x8d, 0x80, 0x80, 0x80, 0x00, 0x01, 0x87, 0x80, 0x80, 0x80, 0x00, 0x00, 0x20, 0x00, 0x10,
23+
0x00, 0xaa, 0x0b
24+
]);
25+
26+
it("Handle compilation failures", done => {
27+
WebAssembly.compile(new Uint8Array([ 1, 2, 3, 4 ])).then(moduleInstance => {
28+
expect(true).toBe(false, "The success callback of the compilation promise was called");
29+
done();
30+
}).catch(e => {
31+
expect(e.name).toEqual("CompileError");
32+
expect(e.message).toEqual("WebAssembly.compile(): expected magic word 00 61 73 6d, found 01 02 03 04 @+0");
33+
done();
34+
});
35+
});
36+
37+
it("Compile and instantiate a WebAssembly module asynchronously", done => {
38+
let importsObj = {
39+
env: {
40+
logarithm: Math.log
41+
}
42+
};
43+
44+
WebAssembly.compile(wasmCode).then(wasmModule => {
45+
WebAssembly.instantiate(wasmModule, importsObj).then(moduleInstance => {
46+
expect(moduleInstance).toBeDefined();
47+
expect(moduleInstance.exports).toBeDefined();
48+
expect(moduleInstance.exports.log).toEqual(jasmine.any(Function));
49+
let actual = moduleInstance.exports.log(Math.E);
50+
expect(actual).toEqual(1);
51+
done();
52+
}).catch(e => {
53+
expect(true).toBe(false, "An unexpected error occurred while instantiating the WebAssembly module: " + e.toString());
54+
done();
55+
});
56+
}).catch(e => {
57+
expect(true).toBe(false, "An unexpected error occurred while compiling the WebAssembly module: " + e.toString());
58+
done();
59+
});
60+
});
61+
62+
it("Compile and instantiate a WebAssembly module inside a worker", done => {
63+
let worker = new Worker("./testWebAssemblyWorker");
64+
65+
worker.onmessage = msg => {
66+
expect(msg.data).toEqual(1);
67+
worker.terminate();
68+
done();
69+
};
70+
71+
worker.postMessage(Array.from(wasmCode));
72+
});
73+
});
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
self.onmessage = function(msg) {
2+
let wasmCode = new Uint8Array(msg.data);
3+
4+
let importsObj = {
5+
env: {
6+
logarithm: Math.log
7+
}
8+
};
9+
10+
WebAssembly.compile(wasmCode).then(wasmModule => {
11+
WebAssembly.instantiate(wasmModule, importsObj).then(moduleInstance => {
12+
let result = moduleInstance.exports.log(Math.E);
13+
self.postMessage(result);
14+
});
15+
});
16+
}

test-app/build-tools/android-metadata-generator/build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ buildscript {
1111
}
1212

1313
dependencies {
14-
classpath 'com.android.tools.build:gradle:3.5.1'
14+
classpath 'com.android.tools.build:gradle:3.5.3'
1515
}
1616
}
1717

@@ -48,6 +48,10 @@ dependencies {
4848
compile 'com.google.code.gson:gson:2.8.5'
4949
compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-metadata-jvm', version: '0.1.0'
5050
compile files("./src/libs/dx.jar")
51+
52+
testCompile 'junit:junit:4.13'
53+
testCompile 'org.mockito:mockito-core:3.0.0'
54+
testImplementation 'junit:junit:4.12'
5155
}
5256

5357
task copyNecessaryFiles {

test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/Builder.java

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
import com.telerik.metadata.parsing.kotlin.extensions.bytecode.BytecodeExtensionFunctionsCollector;
1818
import com.telerik.metadata.parsing.kotlin.metadata.ClassMetadataParser;
1919
import com.telerik.metadata.parsing.kotlin.metadata.bytecode.BytecodeClassMetadataParser;
20+
import com.telerik.metadata.security.MetadataSecurityViolationException;
21+
import com.telerik.metadata.security.classes.SecuredClassRepository;
22+
import com.telerik.metadata.security.classes.SecuredNativeClassDescriptor;
2023
import com.telerik.metadata.storage.functions.FunctionsStorage;
2124
import com.telerik.metadata.storage.functions.extensions.ExtensionFunctionsStorage;
2225

@@ -48,26 +51,26 @@ static TreeNode build(List<String> paths) throws Exception {
4851
if (file.isFile()) {
4952
if (path.endsWith(".jar")) {
5053
JarFile jar = JarFile.readJar(path);
51-
ClassRepo.addToCache(jar);
54+
SecuredClassRepository.INSTANCE.addToCache(jar);
5255
}
5356
} else if (file.isDirectory()) {
5457
ClassDirectory dir = ClassDirectory.readDirectory(path);
55-
ClassRepo.addToCache(dir);
58+
SecuredClassRepository.INSTANCE.addToCache(dir);
5659
}
5760
}
5861
}
5962

6063
TreeNode root = TreeNode.getRoot();
6164

62-
String[] classNames = ClassRepo.getClassNames();
65+
String[] classNames = SecuredClassRepository.INSTANCE.getClassNames();
6366

6467
for (String className : classNames) {
6568
try {
66-
NativeClassDescriptor clazz = ClassRepo.findClass(className);
67-
if (clazz == null) {
68-
throw new ClassNotFoundException("Class " + className + " not found in the input android libraries.");
69+
SecuredNativeClassDescriptor clazz = SecuredClassRepository.INSTANCE.findClass(className);
70+
if (!clazz.isUsageAllowed()) {
71+
throwMetadataSecurityViolationException(className);
6972
} else {
70-
tryCollectKotlinExtensionFunctions(clazz);
73+
tryCollectKotlinExtensionFunctions(clazz.getNativeDescriptor());
7174
}
7275
} catch (Throwable e) {
7376
System.out.println("Skip " + className);
@@ -86,11 +89,11 @@ static TreeNode build(List<String> paths) throws Exception {
8689
// our class path API 17
8790
// Class<?> clazz = Class.forName(className, false, loader);
8891

89-
NativeClassDescriptor clazz = ClassRepo.findClass(className);
90-
if (clazz == null) {
91-
throw new ClassNotFoundException("Class " + className + " not found in the input android libraries.");
92+
SecuredNativeClassDescriptor clazz = SecuredClassRepository.INSTANCE.findClass(className);
93+
if (!clazz.isUsageAllowed()) {
94+
throwMetadataSecurityViolationException(className);
9295
} else {
93-
generate(clazz, root);
96+
generate(clazz.getNativeDescriptor(), root);
9497
}
9598
} catch (Throwable e) {
9699
System.out.println("Skip " + className);
@@ -103,6 +106,10 @@ static TreeNode build(List<String> paths) throws Exception {
103106
return root;
104107
}
105108

109+
private static void throwMetadataSecurityViolationException(String className){
110+
throw new MetadataSecurityViolationException("Class " + className + " could not be used!");
111+
}
112+
106113
private static void tryCollectKotlinExtensionFunctions(NativeClassDescriptor classDescriptor) {
107114
if (classDescriptor instanceof KotlinClassDescriptor) {
108115
ExtensionFunctionsCollector extensionFunctionsCollector = new BytecodeExtensionFunctionsCollector(new BytecodeClassMetadataParser());
@@ -319,8 +326,10 @@ private static void getFieldsFromImplementedInterfaces(NativeClassDescriptor cla
319326
String[] implementedInterfacesNames = clazz.getInterfaceNames();
320327
if (implementedInterfacesNames.length > 0) {
321328
for (String currInterface : implementedInterfacesNames) {
322-
interfaceClass = ClassRepo.findClass(currInterface);
323-
if (interfaceClass != null) {
329+
SecuredNativeClassDescriptor securedNativeClassDescriptor = SecuredClassRepository.INSTANCE.findClass(currInterface);
330+
331+
if (securedNativeClassDescriptor.isUsageAllowed()) {
332+
interfaceClass = securedNativeClassDescriptor.getNativeDescriptor();
324333
fields = interfaceClass.getFields();
325334

326335
// If the interface iteself extends other interfaces - add their fields too
@@ -361,14 +370,14 @@ private static TreeNode getOrCreateNode(TreeNode root, NativeTypeDescriptor type
361370
node = createArrayNode(root, typeName);
362371
} else {
363372
String name = ClassUtil.getCanonicalName(type.getSignature());
364-
NativeClassDescriptor clazz = ClassRepo.findClass(name);
373+
SecuredNativeClassDescriptor clazz = SecuredClassRepository.INSTANCE.findNearestAllowedClass(name);
365374

366375
// if clazz is not found in the ClassRepo, the method/field being analyzed will be skipped
367-
if (clazz == null) {
376+
if (!clazz.isUsageAllowed()) {
368377
return null;
369378
}
370379

371-
node = getOrCreateNode(root, clazz, null);
380+
node = getOrCreateNode(root, clazz.getNativeDescriptor(), null);
372381
}
373382

374383
return node;
@@ -451,10 +460,11 @@ private static TreeNode getOrCreateNode(TreeNode root, NativeClassDescriptor cla
451460
if (node.baseClassNode == null) {
452461
NativeClassDescriptor baseClass = null;
453462
if (predefinedSuperClassname != null) {
454-
baseClass = ClassUtil.getClassByName(predefinedSuperClassname);
463+
SecuredNativeClassDescriptor securedNativeClassDescriptor = SecuredClassRepository.INSTANCE.findNearestAllowedClass(predefinedSuperClassname);
464+
baseClass = securedNativeClassDescriptor.isUsageAllowed() ? securedNativeClassDescriptor.getNativeDescriptor() : null;
455465
} else {
456466
baseClass = clazz.isInterface()
457-
? ClassUtil.getClassByName("java.lang.Object")
467+
? SecuredClassRepository.INSTANCE.findClass("java.lang.Object").getNativeDescriptor() // java.lang.Object should always be available
458468
: ClassUtil.getSuperclass(clazz);
459469
}
460470
if (baseClass != null) {
@@ -505,13 +515,17 @@ private static TreeNode createArrayNode(TreeNode root, String className)
505515
child.nodeType = node.nodeType;
506516
child.arrayElement = node;
507517
} else {
508-
NativeClassDescriptor clazz = ClassRepo.findClass(name);
509-
child.nodeType = clazz.isInterface() ? TreeNode.Interface
510-
: TreeNode.Class;
511-
if (clazz.isStatic()) {
512-
child.nodeType |= TreeNode.Static;
518+
SecuredNativeClassDescriptor securedNativeClassDescriptor = SecuredClassRepository.INSTANCE.findNearestAllowedClass(name);
519+
if (securedNativeClassDescriptor.isUsageAllowed()) {
520+
NativeClassDescriptor nativeClassDescriptor = securedNativeClassDescriptor.getNativeDescriptor();
521+
child.nodeType = nativeClassDescriptor.isInterface() ? TreeNode.Interface
522+
: TreeNode.Class;
523+
if (nativeClassDescriptor.isStatic()) {
524+
child.nodeType |= TreeNode.Static;
525+
}
526+
child.arrayElement = getOrCreateNode(root, nativeClassDescriptor, null);
513527
}
514-
child.arrayElement = getOrCreateNode(root, clazz, null);
528+
515529
}
516530
}
517531

0 commit comments

Comments
 (0)