Skip to content

Commit 44bd694

Browse files
author
Vasil Hristov
authored
Merge pull request #1582 from NativeScript/release
Merge release into master
2 parents 400db05 + 553d3a4 commit 44bd694

File tree

18 files changed

+259
-112
lines changed

18 files changed

+259
-112
lines changed

CHANGELOG.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
1-
6.5.0
2-
==
3-
4-
## What's New
5-
6-
- [Upgrade v8 to 8.0.426.16 (#1579)](https://github.com/NativeScript/android-runtime/issues/1579)
7-
8-
6.4.0
1+
6.4.1
92
==
103

114
## What's New
125

136
- [[FR] Customize metadata generation to avoid adding unnecessary unused JS wrappers (#1485)](https://github.com/NativeScript/android-runtime/issues/1485)
14-
- [Upgrade v8 to 7.9.317.31 (#1526)](https://github.com/NativeScript/android-runtime/issues/1555)
7+
- [Provide verbose metadata filtering output (#1583)](https://github.com/NativeScript/android-runtime/issues/1583)
8+
- [Upgrade v8 to 8.0.426.16 (#1579)](https://github.com/NativeScript/android-runtime/issues/1579)
159
- [Upgrade android gradle plugin to the latest 3.5.3 version (#1564)](https://github.com/NativeScript/android-runtime/issues/1564)
1610

1711
## Bug Fixes
1812

13+
- [Using Android KTX is causing NativeScript app to crash (#1571)](https://github.com/NativeScript/android-runtime/issues/1571)
14+
- [SBG generating conflicting class definitions (#1569)](https://github.com/NativeScript/android-runtime/issues/1569)
1915
- [WebAssembly won't initialize without the debugger (#1558)](https://github.com/NativeScript/android-runtime/issues/1558)
2016
- [Clean up allocations from finalized object links (#1566)](https://github.com/NativeScript/android-runtime/pull/1566)
2117
- [Fix Kotlin Object issue (#1562)](https://github.com/NativeScript/android-runtime/pull/1562)

package.json

Lines changed: 1 addition & 1 deletion
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.4.0",
4+
"version": "6.4.1",
55
"repository": {
66
"type": "git",
77
"url": "https://github.com/NativeScript/android-runtime.git"

test-app/app/build.gradle

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ def computeBuildToolsVersion = { ->
8484
}
8585

8686
def enableAnalytics = (project.hasProperty("gatherAnalyticsData") && project.gatherAnalyticsData == "true")
87+
def enableVerboseMDG = project.gradle.startParameter.logLevel.name() == 'DEBUG'
8788
def analyticsFilePath = "$rootDir/analytics/build-statistics.json"
8889
def analyticsCollector = project.ext.AnalyticsCollector.withOutputPath(analyticsFilePath)
8990
if (enableAnalytics) {
@@ -823,6 +824,10 @@ task buildMetadata(type: BuildToolTask) {
823824
paramz.add("analyticsFilePath=$analyticsFilePath")
824825
}
825826

827+
if(enableVerboseMDG){
828+
paramz.add("verbose")
829+
}
830+
826831
args paramz.toArray()
827832
}
828833
}

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

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
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;
2120
import com.telerik.metadata.security.classes.SecuredClassRepository;
2221
import com.telerik.metadata.security.classes.SecuredNativeClassDescriptor;
2322
import com.telerik.metadata.storage.functions.FunctionsStorage;
2423
import com.telerik.metadata.storage.functions.extensions.ExtensionFunctionsStorage;
24+
import com.telerik.metadata.security.MetadataSecurityViolationException;
2525

2626
import java.io.File;
2727
import java.util.ArrayList;
@@ -67,9 +67,7 @@ static TreeNode build(List<String> paths) throws Exception {
6767
for (String className : classNames) {
6868
try {
6969
SecuredNativeClassDescriptor clazz = SecuredClassRepository.INSTANCE.findClass(className);
70-
if (!clazz.isUsageAllowed()) {
71-
throwMetadataSecurityViolationException(className);
72-
} else {
70+
if (clazz.isUsageAllowed()) {
7371
tryCollectKotlinExtensionFunctions(clazz.getNativeDescriptor());
7472
}
7573
} catch (Throwable e) {
@@ -90,9 +88,7 @@ static TreeNode build(List<String> paths) throws Exception {
9088
// Class<?> clazz = Class.forName(className, false, loader);
9189

9290
SecuredNativeClassDescriptor clazz = SecuredClassRepository.INSTANCE.findClass(className);
93-
if (!clazz.isUsageAllowed()) {
94-
throwMetadataSecurityViolationException(className);
95-
} else {
91+
if (clazz.isUsageAllowed()) {
9692
generate(clazz.getNativeDescriptor(), root);
9793
}
9894
} catch (Throwable e) {
@@ -106,10 +102,6 @@ static TreeNode build(List<String> paths) throws Exception {
106102
return root;
107103
}
108104

109-
private static void throwMetadataSecurityViolationException(String className){
110-
throw new MetadataSecurityViolationException("Class " + className + " could not be used!");
111-
}
112-
113105
private static void tryCollectKotlinExtensionFunctions(NativeClassDescriptor classDescriptor) {
114106
if (classDescriptor instanceof KotlinClassDescriptor) {
115107
ExtensionFunctionsCollector extensionFunctionsCollector = new BytecodeExtensionFunctionsCollector(new BytecodeClassMetadataParser());
@@ -196,31 +188,30 @@ private static void setNodeMembers(NativeClassDescriptor clazz, TreeNode node, T
196188
private static void setMethodsInfo(TreeNode root, TreeNode node, NativeClassDescriptor clazz, NativeMethodDescriptor[] ownMethodDescriptors, NativeMethodDescriptor[] ownAndParentMethodDescriptors, Map<String, MethodInfo> existingNodeMethods, boolean hasClassMetadataInfo) throws Exception {
197189

198190

199-
for (NativeMethodDescriptor m : ownMethodDescriptors) {
200-
if (m.isSynthetic()) {
191+
for (NativeMethodDescriptor ownMethod : ownMethodDescriptors) {
192+
if (ownMethod.isSynthetic()) {
201193
continue;
202194
}
203195

204-
if (hasClassMetadataInfo && !m.getName().equals("<init>")) {
205-
MetadataInfoAnnotationDescriptor metadataInfo = m.getMetadataInfoAnnotation();
196+
if (hasClassMetadataInfo && !ownMethod.getName().equals("<init>")) {
197+
MetadataInfoAnnotationDescriptor metadataInfo = ownMethod.getMetadataInfoAnnotation();
206198
if ((metadataInfo != null) && metadataInfo.skip()) {
207199
continue;
208200
}
209201
}
210202

211-
if (m.isPublic() || m.isProtected()) {
212-
boolean isStatic = m.isStatic();
203+
if (ownMethod.isPublic() || ownMethod.isProtected()) {
204+
boolean isStatic = ownMethod.isStatic();
205+
206+
MethodInfo mi = new MethodInfo(ownMethod);
213207

214-
MethodInfo mi = new MethodInfo(m);
215208
int countUnique = 0;
216-
for (NativeMethodDescriptor m1 : ownAndParentMethodDescriptors) {
217-
boolean m1IsStatic = m1.isStatic();
218-
if (!m1.isSynthetic()
219-
&& (m1.isPublic() || m1.isProtected())
209+
for (NativeMethodDescriptor ownOrParentMethod : ownAndParentMethodDescriptors) {
210+
boolean m1IsStatic = ownOrParentMethod.isStatic();
211+
if (!ownOrParentMethod.isSynthetic()
212+
&& (ownOrParentMethod.isPublic() || ownOrParentMethod.isProtected())
220213
&& (isStatic == m1IsStatic)
221-
&& (m1.getName().equals(mi.name) && (m1
222-
.getArgumentTypes().length == m
223-
.getArgumentTypes().length))) {
214+
&& (ownOrParentMethod.getName().equals(mi.name) && (ownOrParentMethod.getArgumentTypes().length == ownMethod.getArgumentTypes().length))) {
224215
if (++countUnique > 1) {
225216
break;
226217
}
@@ -229,8 +220,8 @@ private static void setMethodsInfo(TreeNode root, TreeNode node, NativeClassDesc
229220
mi.isResolved = countUnique == 1;
230221

231222

232-
NativeTypeDescriptor[] params = m.getArgumentTypes();
233-
mi.signature = getMethodSignature(root, m.getReturnType(),
223+
NativeTypeDescriptor[] params = ownMethod.getArgumentTypes();
224+
mi.signature = getMethodSignature(root, ownMethod.getReturnType(),
234225
params);
235226

236227
if (mi.signature != null) {
@@ -239,11 +230,11 @@ private static void setMethodsInfo(TreeNode root, TreeNode node, NativeClassDesc
239230
mi.declaringType = getOrCreateNode(root, clazz, null);
240231
node.staticMethods.add(mi);
241232
} else {
242-
mi.declaringType = getOrCreateNode(root, m.getDeclaringClass(), null);
233+
mi.declaringType = getOrCreateNode(root, ownMethod.getDeclaringClass(), null);
243234
node.addExtensionFunction(mi);
244235
}
245236
} else {
246-
String sig = m.getName() + m.getSignature();
237+
String sig = ownMethod.getName() + ownMethod.getSignature();
247238
if (existingNodeMethods.containsKey(sig)) {
248239
continue;
249240
}

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.telerik.metadata.analytics.AnalyticsConfiguration;
44
import com.telerik.metadata.security.filtering.input.user.UserPatternsCollection;
5+
import com.telerik.metadata.security.logging.console.MetadataFilterConsoleLogger;
56

67
import java.io.BufferedReader;
78
import java.io.File;
@@ -15,6 +16,7 @@
1516

1617
public class Generator {
1718

19+
private static final String VERBOSE_FLAG_NAME = "verbose";
1820
private static final String ANALYTICS_ARGUMENT_BEGINNING = "analyticsFilePath=";
1921
private static final String MDG_OUTPUT_DIR = "mdg-output-dir.txt";
2022
private static final String MDG_JAVA_DEPENDENCIES = "mdg-java-dependencies.txt";
@@ -25,7 +27,7 @@ public class Generator {
2527
* @param args
2628
*/
2729
public static void main(String[] args) {
28-
enableAnalyticsBasedOnArgs(args);
30+
enableFlaggedFeatures(args);
2931
UserPatternsCollection.INSTANCE.populateWhitelistEntriesFromFile(MDG_WHITELIST);
3032
UserPatternsCollection.INSTANCE.populateBlacklistEntriesFromFile(MDG_BLACKLIST);
3133

@@ -63,17 +65,19 @@ public static void main(String[] args) {
6365
}
6466
}
6567

66-
private static void enableAnalyticsBasedOnArgs(String[] args){
68+
private static void enableFlaggedFeatures(String[] args) {
6769
for (String arg : args) {
6870
if (arg.startsWith(ANALYTICS_ARGUMENT_BEGINNING)) {
6971
String filePath = arg.replace(ANALYTICS_ARGUMENT_BEGINNING, "");
7072
AnalyticsConfiguration.enableAnalytics(filePath);
73+
} else if (VERBOSE_FLAG_NAME.equals(arg)) {
74+
MetadataFilterConsoleLogger.INSTANCE.setEnabled(true);
7175
}
7276
}
7377
}
7478

7579
public static List<String> getFileRows(String filename) throws IOException {
76-
List<String> rows = new ArrayList<String>();
80+
List<String> rows = new ArrayList<>();
7781
BufferedReader br = null;
7882
try {
7983
br = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,6 @@ public void writeClassValue(StreamWriter writer,
114114
writeInt(commonInterfacePrefixPosition, writer);
115115
}
116116

117-
int len = writeLength(n.instanceMethods.size(), writer);
118-
for (int i = 0; i < len; i++) {
119-
writeMethodInfo(n.instanceMethods.get(i), stringsMap, writer);
120-
}
121-
122117
List<MethodInfo> extensionFunctions = n.getExtensionFunctions();
123118

124119
writeLength(extensionFunctions.size(), writer);
@@ -127,6 +122,11 @@ public void writeClassValue(StreamWriter writer,
127122
writeTreeNodeId(extensionFunction.declaringType, writer);
128123
}
129124

125+
int len = writeLength(n.instanceMethods.size(), writer);
126+
for (int i = 0; i < len; i++) {
127+
writeMethodInfo(n.instanceMethods.get(i), stringsMap, writer);
128+
}
129+
130130
len = writeLength(n.instanceFields.size(), writer);
131131
for (int i = 0; i < len; i++) {
132132
FieldInfo fi = n.instanceFields.get(i);

test-app/build-tools/android-metadata-generator/src/src/com/telerik/metadata/security/classes/SecuredClassRepository.kt

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,32 @@ import com.telerik.metadata.security.filtering.blacklisting.MetadataBlacklist
66
import com.telerik.metadata.security.filtering.input.user.UserPatternsCollection
77
import com.telerik.metadata.security.filtering.matching.impl.PatternMatcherImpl
88
import com.telerik.metadata.security.filtering.whitelisting.MetadataWhitelist
9+
import com.telerik.metadata.security.logging.console.MetadataFilterConsoleLogger
910
import java.util.*
11+
import kotlin.collections.HashSet
1012

1113
object SecuredClassRepository {
1214
private val cachedProviders = ArrayList<ClassMapProvider>()
1315
private val patternMatcher = PatternMatcherImpl()
1416
private val whitelist = MetadataWhitelist(UserPatternsCollection.whitelistEntries, patternMatcher)
1517
private val blacklist = MetadataBlacklist(UserPatternsCollection.blacklistEntries, patternMatcher)
18+
private val alreadyLoggedClasses = HashSet<Pair<String, String>>()
1619

1720
fun addToCache(classMapProvider: ClassMapProvider) {
1821
cachedProviders.add(classMapProvider)
1922
}
2023

24+
private fun NativeClassDescriptor.getSimplifiedClassName() = this.className.substring(this.packageName.length).replace('$', '.').trimStart('.')
25+
2126
fun findClass(className: String): SecuredNativeClassDescriptor {
2227
val clazz: NativeClassDescriptor? = findClassFromProviders(className)
2328

2429
if (clazz != null) {
25-
val simplifiedClassName = clazz.className.substring(clazz.packageName.length).replace('$', '.').trimStart('.')
26-
27-
val isAllowedByWhitelist = whitelist.isAllowed(clazz.packageName, simplifiedClassName)
28-
if (isAllowedByWhitelist) {
30+
val simplifiedClassName = clazz.getSimplifiedClassName()
2931

30-
val isAllowedByBlacklist = blacklist.isAllowed(clazz.packageName, simplifiedClassName)
31-
if (isAllowedByBlacklist) {
32-
return SecuredNativeClassDescriptor(true, clazz)
33-
}
32+
val isUsageAllowed = isClassUsageAllowed(clazz.packageName, simplifiedClassName)
33+
if (isUsageAllowed) {
34+
return SecuredNativeClassDescriptor(true, clazz)
3435
}
3536
}
3637

@@ -41,15 +42,11 @@ object SecuredClassRepository {
4142
var clazz: NativeClassDescriptor? = findClassFromProviders(className)
4243

4344
while (clazz != null) {
44-
val simplifiedClassName = clazz.className.substring(clazz.packageName.length).replace('$', '.').trimStart('.')
45+
val simplifiedClassName = clazz.getSimplifiedClassName()
4546

46-
val isAllowedByWhitelist = whitelist.isAllowed(clazz.packageName, simplifiedClassName)
47-
if (isAllowedByWhitelist) {
48-
49-
val isAllowedByBlacklist = blacklist.isAllowed(clazz.packageName, simplifiedClassName)
50-
if (isAllowedByBlacklist) {
51-
return SecuredNativeClassDescriptor(true, clazz)
52-
}
47+
val isUsageAllowed = isClassUsageAllowed(clazz.packageName, simplifiedClassName)
48+
if (isUsageAllowed) {
49+
return SecuredNativeClassDescriptor(true, clazz)
5350
}
5451

5552
clazz = findClassFromProviders(clazz.superclassName)
@@ -58,6 +55,29 @@ object SecuredClassRepository {
5855
return SecuredNativeClassDescriptor(false, NativeClassDescriptor.Missing)
5956
}
6057

58+
private fun isClassUsageAllowed(packageName: String, className: String): Boolean {
59+
val whitelistFilterResult = whitelist.isAllowed(packageName, className)
60+
val blacklistFilterResult = blacklist.isAllowed(packageName, className)
61+
62+
val packageAndClassNamePair = packageName to className
63+
64+
if (whitelistFilterResult.isAllowed && blacklistFilterResult.isAllowed) {
65+
if (packageAndClassNamePair !in alreadyLoggedClasses) {
66+
MetadataFilterConsoleLogger.logAllowed(packageName, className, whitelistFilterResult, blacklistFilterResult)
67+
alreadyLoggedClasses.add(packageAndClassNamePair)
68+
}
69+
70+
return true
71+
}
72+
73+
if (packageAndClassNamePair !in alreadyLoggedClasses) {
74+
MetadataFilterConsoleLogger.logDisallowed(packageName, className, whitelistFilterResult, blacklistFilterResult)
75+
alreadyLoggedClasses.add(packageAndClassNamePair)
76+
}
77+
78+
return false
79+
}
80+
6181
private fun findClassFromProviders(className: String): NativeClassDescriptor? {
6282
var clazz: NativeClassDescriptor? = null
6383
for (classMapProvider in cachedProviders) {
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.telerik.metadata.security.filtering
22

33
interface MetadataFilter {
4-
fun isAllowed(packageName: String, className: String): Boolean
4+
fun isAllowed(packageName: String, className: String): MetadataFilterResult
55
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package com.telerik.metadata.security.filtering
2+
3+
import com.telerik.metadata.security.filtering.input.PatternEntry
4+
import java.util.*
5+
6+
data class MetadataFilterResult(val isAllowed: Boolean, val matchedPatternEntry: Optional<PatternEntry> = Optional.empty())
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
package com.telerik.metadata.security.filtering.blacklisting
22

33
import com.telerik.metadata.security.filtering.MetadataFilter
4+
import com.telerik.metadata.security.filtering.MetadataFilterResult
45
import com.telerik.metadata.security.filtering.input.PatternEntry
56
import com.telerik.metadata.security.filtering.matching.PatternMatcher
7+
import java.util.*
68

79
class MetadataBlacklist(private val userInput: Collection<PatternEntry>, private val patternMatcher: PatternMatcher) : MetadataFilter {
810

9-
override fun isAllowed(packageName: String, className: String) = !userInput.any { inputEntry ->
10-
(inputEntry.packagePattern.isEmpty() || patternMatcher.match(inputEntry.packagePattern, packageName))
11-
&& (inputEntry.classPattern.isEmpty() || patternMatcher.match(inputEntry.classPattern, className))
11+
override fun isAllowed(packageName: String, className: String): MetadataFilterResult {
12+
val responsiblePatternEntry = userInput.firstOrNull { inputEntry ->
13+
(inputEntry.packagePattern.isEmpty() || patternMatcher.match(inputEntry.packagePattern, packageName))
14+
&& (inputEntry.classPattern.isEmpty() || patternMatcher.match(inputEntry.classPattern, className))
15+
}
16+
17+
return if (responsiblePatternEntry != null) MetadataFilterResult(false, Optional.of(responsiblePatternEntry)) else MetadataFilterResult(true)
1218
}
1319
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
package com.telerik.metadata.security.filtering.input
22

3-
data class PatternEntry(val packagePattern: String, val classPattern: String)
3+
data class PatternEntry(val packagePattern: String, val classPattern: String) {
4+
companion object {
5+
fun empty(): PatternEntry {
6+
return PatternEntry("", "")
7+
}
8+
}
9+
10+
override fun toString() = "$packagePattern:$classPattern"
11+
}

0 commit comments

Comments
 (0)