Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: generate correct metadata when overflowing signed short values #1821

Merged
merged 1 commit into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class Generator {
private static final String MDG_BLACKLIST = "blacklist.mdg";
private static final String METADATA_JAVA_OUT = "mdg-java-out.txt";

private static boolean verbose_mode = false;

/**
* @param args arguments
*/
Expand Down Expand Up @@ -69,7 +71,13 @@ public static void main(String[] args) {
FileOutputStream oss = new FileOutputStream(new File(metadataOutputDir, "treeStringsStream.dat"));
FileStreamWriter outStringsStream = new FileStreamWriter(oss);

new Writer(outNodeStream, outValueStream, outStringsStream).writeTree(root);
if (verbose_mode) {
FileOutputStream ods = new FileOutputStream(new File("metadata-debug.json"));
FileStreamWriter outDebugStream = new FileStreamWriter(ods);
new Writer(outNodeStream, outValueStream, outStringsStream, outDebugStream).writeTree(root);
} else {
new Writer(outNodeStream, outValueStream, outStringsStream).writeTree(root);
}
} catch (Throwable ex) {
System.err.println(String.format("Error executing Metadata Generator: %s", ex.getMessage()));
ex.printStackTrace(System.out);
Expand All @@ -83,6 +91,7 @@ private static void enableFlaggedFeatures(String[] args) {
String filePath = arg.replace(ANALYTICS_ARGUMENT_BEGINNING, "");
AnalyticsConfiguration.enableAnalytics(filePath);
} else if (VERBOSE_FLAG_NAME.equals(arg)) {
verbose_mode = true;
MetadataFilterConsoleLogger.INSTANCE.setEnabled(true);
} else if (SKIP_FLAG_NAME.equals(arg)) {
System.out.println("Skipping metadata generation: skip flag used.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.telerik.metadata;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.telerik.metadata.TreeNode.FieldInfo;
import com.telerik.metadata.TreeNode.MethodInfo;

Expand All @@ -10,6 +12,7 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;

Expand All @@ -18,14 +21,20 @@ public class Writer {
private final StreamWriter outNodeStream;
private final StreamWriter outValueStream;
private final StreamWriter outStringsStream;
private final StreamWriter outDebugStream;

private int commonInterfacePrefixPosition;

public Writer(StreamWriter outNodeStream, StreamWriter outValueStream,
StreamWriter outStringsStream) {
this(outNodeStream, outValueStream, outStringsStream, null);
}
public Writer(StreamWriter outNodeStream, StreamWriter outValueStream,
StreamWriter outStringsStream, StreamWriter outDebugStream) {
this.outNodeStream = outNodeStream;
this.outValueStream = outValueStream;
this.outStringsStream = outStringsStream;
this.outDebugStream = outDebugStream;
}

private final static byte[] writeUniqueName_lenBuff = new byte[2];
Expand Down Expand Up @@ -214,6 +223,10 @@ public void writeTree(TreeNode root) throws Exception {
d.push(root);
while (!d.isEmpty()) {
TreeNode n = d.pollFirst();
if (Short.toUnsignedInt((short)(curId + 1)) < Short.toUnsignedInt(curId)) {
// we have overflowed our maximum (16 bit) metadata size
throw new Exception("Metadata is too big and has overflown our current limit, please report this issue");
}
n.id = n.firstChildId = n.nextSiblingId = curId++;

String name = n.getName();
Expand Down Expand Up @@ -351,7 +364,7 @@ public void writeTree(TreeNode root) throws Exception {
while (!d.isEmpty()) {
TreeNode n = d.pollFirst();

nodeData[0] = n.firstChildId + (n.nextSiblingId << 16);
nodeData[0] = (n.firstChildId & 0xFFFF) | (n.nextSiblingId << 16);
nodeData[1] = n.offsetName;
nodeData[2] = n.offsetValue;

Expand All @@ -364,5 +377,24 @@ public void writeTree(TreeNode root) throws Exception {

outNodeStream.flush();
outNodeStream.close();

if (outDebugStream != null) {
d.push(root);
JsonArray rootArray = new JsonArray();
while (!d.isEmpty()) {
TreeNode n = d.pollFirst();
JsonObject obj = new JsonObject();
obj.addProperty("id", Short.toUnsignedInt(n.id));
obj.addProperty("nextSiblingId", Short.toUnsignedInt(n.nextSiblingId));
obj.addProperty("firstChildId", Short.toUnsignedInt(n.firstChildId));
obj.addProperty("name", n.getName());
obj.addProperty("nodeType", n.nodeType);
rootArray.add(obj);
d.addAll(n.children);
}
outDebugStream.write(rootArray.toString().getBytes());
outDebugStream.flush();
outDebugStream.close();
}
}
}
17 changes: 13 additions & 4 deletions test-app/runtime/src/main/cpp/MetadataReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "MetadataMethodInfo.h"
#include "Util.h"
#include <sstream>
#include <android/log.h>

using namespace std;
using namespace tns;
Expand Down Expand Up @@ -54,20 +55,28 @@ MetadataTreeNode* MetadataReader::BuildTree() {
while (true) {

uint16_t childNodeDataId = childNodeData - rootNodeData;

MetadataTreeNode* childNode;
// node (and its next siblings) already visited, so we don't need to visit it again
if (m_v[childNodeDataId] != emptyNode) {
childNode = m_v[childNodeDataId];
__android_log_print(ANDROID_LOG_ERROR, "TNS.error", "Consistency error in metadata. A child should never have been visited before its parent. Parent: %s Child: %s. Child metadata id: %u", node->name.c_str(), childNode->name.c_str(), childNodeDataId);
break;
} else {
childNode = new MetadataTreeNode;
childNode->name = ReadName(childNodeData->offsetName);
childNode->offsetValue = childNodeData->offsetValue;
}

MetadataTreeNode* childNode = new MetadataTreeNode;
childNode->parent = node;
childNode->name = ReadName(childNodeData->offsetName);
childNode->offsetValue = childNodeData->offsetValue;

node->children->push_back(childNode);

m_v[childNodeDataId] = childNode;

if (childNodeDataId == childNodeData->nextSiblingId) {
break;
}

childNodeData = rootNodeData + childNodeData->nextSiblingId;
}
}
Expand Down
Loading