Skip to content
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
18 changes: 18 additions & 0 deletions src/dalvikExecutableParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3047,6 +3047,24 @@ const createDalvikExecutableParser = <Instructions>({
};
});

// Sort parameter annotations in each class by method index in classData
for (const classDef of classDefinitions) {
if (classDef.annotations?.parameterAnnotations && classDef.classData) {
const allMethods = [...(classDef.classData.directMethods ?? []), ...(classDef.classData.virtualMethods ?? [])];
classDef.annotations.parameterAnnotations.sort((a, b) => {
const indexA = allMethods.findIndex(m =>
m.method.name === a.method.name &&
m.method.prototype.shorty === a.method.prototype.shorty
);
const indexB = allMethods.findIndex(m =>
m.method.name === b.method.name &&
m.method.prototype.shorty === b.method.prototype.shorty
);
return indexA - indexB;
});
}
}

return {
classDefinitions,
link,
Expand Down
33 changes: 0 additions & 33 deletions src/dalvikExecutableParserAgainstSmaliParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,31 +54,6 @@ function normalizeSmaliFilePath(smaliFilePath: string | {
};
}

function sortParameterAnnotations(classDefinition: any) {
if (
classDefinition
&& typeof classDefinition === 'object'
&& 'annotations' in classDefinition
&& classDefinition.annotations
&& typeof classDefinition.annotations === 'object'
&& 'parameterAnnotations' in classDefinition.annotations
&& Array.isArray(classDefinition.annotations.parameterAnnotations)
) {
classDefinition.annotations.parameterAnnotations.sort((a: any, b: any) => {
// Sort by class name first
if (a.method.class !== b.method.class) {
return a.method.class.localeCompare(b.method.class);
}
// Then by method name
if (a.method.name !== b.method.name) {
return a.method.name.localeCompare(b.method.name);
}
// Then by shorty (prototype signature)
return a.method.prototype.shorty.localeCompare(b.method.prototype.shorty);
});
}
}

function sortFieldAnnotations(classDefinition: any) {
if (
classDefinition
Expand Down Expand Up @@ -165,10 +140,6 @@ const parseDexAgainstSmaliMacro = test.macro({
normalizeClassDefinition(classDefinitionFromDex);
normalizeClassDefinition(classDefinitionFromSmali);

// Sort parameter annotations to ensure consistent ordering between DEX and Smali
sortParameterAnnotations(classDefinitionFromDex);
sortParameterAnnotations(classDefinitionFromSmali);

// Sort field annotations to ensure consistent ordering between DEX and Smali
sortFieldAnnotations(classDefinitionFromDex);
sortFieldAnnotations(classDefinitionFromSmali);
Expand Down Expand Up @@ -400,10 +371,6 @@ test.serial(
normalizeClassDefinition(classDefinitionFromDex);
normalizeClassDefinition(classDefinitionFromSmali);

// Sort parameter annotations to ensure consistent ordering between DEX and Smali
sortParameterAnnotations(classDefinitionFromDex);
sortParameterAnnotations(classDefinitionFromSmali);

// Sort field annotations to ensure consistent ordering between DEX and Smali
sortFieldAnnotations(classDefinitionFromDex);
sortFieldAnnotations(classDefinitionFromSmali);
Expand Down
9 changes: 9 additions & 0 deletions src/smaliParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2511,6 +2511,15 @@ const smaliMethodsParser: Parser<SmaliMethods, string> = promiseCompose(
invariant(false, 'Expected method type');
}

// Sort parameter annotations by method index in the combined method list
// to match the order in the DEX file's annotations directory
const allMethods = [...directMethods, ...virtualMethods];
parameterAnnotations.sort((a, b) => {
const indexA = allMethods.findIndex(m => dalvikExecutableMethodEquals(m.method, a.method));
const indexB = allMethods.findIndex(m => dalvikExecutableMethodEquals(m.method, b.method));
return indexA - indexB;
});

return {
directMethods,
virtualMethods,
Expand Down