From 8b924f718e57a8c98af913187a3f99b09ca18ef8 Mon Sep 17 00:00:00 2001 From: dev747368 <48332326+dev747368@users.noreply.github.com> Date: Mon, 8 Aug 2022 21:36:10 +0000 Subject: [PATCH] GP-2435 fix exception in QueryOptionService if secondary isn't an intstr --- .../app/util/opinion/QueryOpinionService.java | 86 ++++++++++--------- .../util/opinion/QueryOpinionServiceTest.java | 18 ++++ .../Processors/ARM/data/languages/ARM.opinion | 9 ++ .../MIPS/data/languages/MIPS.opinion | 9 ++ 4 files changed, 83 insertions(+), 39 deletions(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/QueryOpinionService.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/QueryOpinionService.java index e9e1caeb70..03908b1f74 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/QueryOpinionService.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/QueryOpinionService.java @@ -15,9 +15,10 @@ */ package ghidra.app.util.opinion; -import java.io.IOException; import java.util.*; +import java.io.IOException; + import org.apache.commons.lang3.StringUtils; import org.xml.sax.*; @@ -206,53 +207,60 @@ public class QueryOpinionService { return queryResult; } - static boolean secondaryAttributeMatches(String eFlagsDecimalString, String attribute) { - - // eFlagDecimalString is the elf e_flags value, as a decimal string - // sa is the secondary attribute string from the opinion file, - // and it must start with "0x" or "0b" - if (attribute == null) { + /** + * Match a secondaryKey value string against a binary or hex formatted constraint. + *

+ * The constraint value needs to be patterned as: + *

  • Binary: "0b1110_0001 111..." (spaces and "_" ignored, dots are wildcards) + *
  • Hex: "0xaabb_ccdd" (hex digits, spaces and "_" ignored) + * + * @param secondaryKey decimal integer string that is being searched for + * @param constraint value or pattern that the secondaryKey is being compared against + * @return boolean true if the secondaryKey matches the constraint; false if it doesn't match + * or if the constraint isn't a binary or hex constraint, or if the secondaryKey value isn't + * an integer + */ + static boolean secondaryAttributeMatches(String secondaryKey, String constraint) { + if (constraint == null) { return false; } - if (!StringUtils.startsWithAny(attribute.toLowerCase(), "0x", "0b")) { + int secondaryKeyInt; + try { + secondaryKeyInt = Integer.parseInt(secondaryKey); + } + catch (NumberFormatException e) { return false; } - int eFlagsInt = Integer.parseInt(eFlagsDecimalString); - String eFlagsBinaryString = Integer.toBinaryString(eFlagsInt); - if (eFlagsBinaryString == null) { - return false; - } - - eFlagsBinaryString = StringUtils.leftPad(eFlagsBinaryString, 32, "0"); - String eFlagsHexString = Integer.toHexString(eFlagsInt); - eFlagsHexString = StringUtils.leftPad(eFlagsHexString, 8, "0"); - - // Remove '_' and whitespace from the attribute string - String cleaned = attribute.replace("_", "").replaceAll("\\s+", "").trim(); - String prefix = cleaned.substring(0, 2); - String value = cleaned.substring(2); - if (prefix.toLowerCase().startsWith("0x")) { - - // It's a hex string - value = StringUtils.leftPad(value, 8, "0"); - return value.equals(eFlagsHexString); - } - - // It's a binary string - value = StringUtils.leftPad(value, 32, "0"); - for (int i = 0; i < 32; i++) { - char c = value.charAt(i); - if (c == '.') { // wildcard - continue; + constraint = constraint.replaceAll("[_\\s]+", "").trim().toLowerCase(); + if (constraint.startsWith("0x")) { // Hex constraint string + try { + int hexConstraint = Integer.parseUnsignedInt(constraint.substring(2), 16); + return secondaryKeyInt == hexConstraint; } - - if (eFlagsBinaryString.charAt(i) != c) { - return false; + catch (NumberFormatException e) { + // fall thru, return false } + return false; } + else if (constraint.startsWith("0b")) { // Binary constraint string + String secondaryKeyBinaryString = Integer.toBinaryString(secondaryKeyInt); + secondaryKeyBinaryString = StringUtils.leftPad(secondaryKeyBinaryString, 32, "0"); - return true; + String constraintBinaryString = StringUtils.leftPad(constraint.substring(2), 32, "0"); + for (int i = 0; i < 32; i++) { + char c = constraintBinaryString.charAt(i); + if (c == '.') { // wildcard + continue; + } + + if (secondaryKeyBinaryString.charAt(i) != c) { + return false; + } + } + return true; + } + return false; } } diff --git a/Ghidra/Features/Base/src/test/java/ghidra/app/util/opinion/QueryOpinionServiceTest.java b/Ghidra/Features/Base/src/test/java/ghidra/app/util/opinion/QueryOpinionServiceTest.java index 0d55819a57..e489a4ac57 100644 --- a/Ghidra/Features/Base/src/test/java/ghidra/app/util/opinion/QueryOpinionServiceTest.java +++ b/Ghidra/Features/Base/src/test/java/ghidra/app/util/opinion/QueryOpinionServiceTest.java @@ -50,4 +50,22 @@ public class QueryOpinionServiceTest { } + @Test + public void testHexConstraint() { + assertTrue(QueryOpinionService.secondaryAttributeMatches("85", "0x55")); + assertTrue(QueryOpinionService.secondaryAttributeMatches("-1", "0xff ff_ff ff")); + } + + @Test + public void testNotBinaryOrHexConstraint() { + assertFalse(QueryOpinionService.secondaryAttributeMatches("1", "not_a_valid_constraint")); + assertFalse(QueryOpinionService.secondaryAttributeMatches("1", "0b1x")); + assertFalse(QueryOpinionService.secondaryAttributeMatches("1", "")); + } + + @Test + public void testNotIntegerKey() { + assertFalse(QueryOpinionService.secondaryAttributeMatches("abc", "0x1")); + assertFalse(QueryOpinionService.secondaryAttributeMatches("", "0b....")); + } } diff --git a/Ghidra/Processors/ARM/data/languages/ARM.opinion b/Ghidra/Processors/ARM/data/languages/ARM.opinion index 64634f1136..49302336f4 100644 --- a/Ghidra/Processors/ARM/data/languages/ARM.opinion +++ b/Ghidra/Processors/ARM/data/languages/ARM.opinion @@ -1,4 +1,13 @@ + diff --git a/Ghidra/Processors/MIPS/data/languages/MIPS.opinion b/Ghidra/Processors/MIPS/data/languages/MIPS.opinion index 48698d8a21..a739a3631f 100644 --- a/Ghidra/Processors/MIPS/data/languages/MIPS.opinion +++ b/Ghidra/Processors/MIPS/data/languages/MIPS.opinion @@ -1,4 +1,13 @@ +