diff options
| author | Glenn Smith <glenn@vector35.com> | 2022-02-15 20:08:06 -0500 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2022-02-16 15:32:39 -0500 |
| commit | 925323f286e2ff2b866c2c65cdcc342cafa4afe7 (patch) | |
| tree | 0540cb24a37fad76fa46d20af49c0a6ac402b916 | |
| parent | ff9ee07f19597d90ac68d0bd04ab58947f2e604f (diff) | |
Escape type names and definitions
Closes #2427, #2585, #1658, #1632, probably others
| -rw-r--r-- | binaryninjaapi.h | 24 | ||||
| -rw-r--r-- | binaryninjacore.h | 28 | ||||
| -rw-r--r-- | python/types.py | 129 | ||||
| -rw-r--r-- | rust/src/types.rs | 2 | ||||
| -rw-r--r-- | suite/api_test.py | 60 | ||||
| -rw-r--r-- | type.cpp | 56 |
6 files changed, 242 insertions, 57 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index e89a572a..d0feb2d1 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1267,10 +1267,13 @@ namespace BinaryNinja { virtual size_t size() const; virtual size_t StringSize() const; - virtual std::string GetString() const; + virtual std::string GetString(BNTokenEscapingType escaping = NoTokenEscapingType) const; virtual std::string GetJoinString() const { return m_join; } virtual bool IsEmpty() const { return m_name.size() == 0; } + static std::string EscapeTypeName(const std::string& name, BNTokenEscapingType escaping); + static std::string UnescapeTypeName(const std::string& name, BNTokenEscapingType escaping); + BNNameList GetAPIObject() const; static void FreeAPIObject(BNNameList* name); static NameList FromAPIObject(BNNameList* name); @@ -2932,17 +2935,20 @@ namespace BinaryNinja { uint64_t GetElementCount() const; uint64_t GetOffset() const; - std::string GetString(Platform* platform = nullptr) const; - std::string GetTypeAndName(const QualifiedName& name) const; - std::string GetStringBeforeName(Platform* platform = nullptr) const; - std::string GetStringAfterName(Platform* platform = nullptr) const; + std::string GetString(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const; + std::string GetTypeAndName(const QualifiedName& name, BNTokenEscapingType escaping = NoTokenEscapingType) const; + std::string GetStringBeforeName(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const; + std::string GetStringAfterName(Platform* platform = nullptr, BNTokenEscapingType escaping = NoTokenEscapingType) const; std::vector<InstructionTextToken> GetTokens( - Platform* platform = nullptr, uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + Platform* platform = nullptr, uint8_t baseConfidence = BN_FULL_CONFIDENCE, + BNTokenEscapingType escaping = NoTokenEscapingType) const; std::vector<InstructionTextToken> GetTokensBeforeName( - Platform* platform = nullptr, uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + Platform* platform = nullptr, uint8_t baseConfidence = BN_FULL_CONFIDENCE, + BNTokenEscapingType escaping = NoTokenEscapingType) const; std::vector<InstructionTextToken> GetTokensAfterName( - Platform* platform = nullptr, uint8_t baseConfidence = BN_FULL_CONFIDENCE) const; + Platform* platform = nullptr, uint8_t baseConfidence = BN_FULL_CONFIDENCE, + BNTokenEscapingType escaping = NoTokenEscapingType) const; Ref<Type> Duplicate() const; @@ -3014,7 +3020,7 @@ namespace BinaryNinja { bool AddTypeMemberTokens(BinaryView* data, std::vector<InstructionTextToken>& tokens, int64_t offset, std::vector<std::string>& nameList, size_t size = 0, bool indirect = false); std::vector<TypeDefinitionLine> GetLines(Ref<BinaryView> data, const std::string& name, - int lineWidth = 80, bool collapsed = false); + int lineWidth = 80, bool collapsed = false, BNTokenEscapingType escaping = NoTokenEscapingType); static std::string GetSizeSuffix(size_t size); }; diff --git a/binaryninjacore.h b/binaryninjacore.h index 25500d0b..e72830a1 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -28,14 +28,14 @@ // Current ABI version for linking to the core. This is incremented any time // there are changes to the API that affect linking, including new functions, // new types, or modifications to existing functions or types. -#define BN_CURRENT_CORE_ABI_VERSION 17 +#define BN_CURRENT_CORE_ABI_VERSION 18 // Minimum ABI version that is supported for loading of plugins. Plugins that // are linked to an ABI version less than this will not be able to load and // will require rebuilding. The minimum version is increased when there are // incompatible changes that break binary compatibility, such as changes to // existing types or functions. -#define BN_MINIMUM_CORE_ABI_VERSION 13 +#define BN_MINIMUM_CORE_ABI_VERSION 18 #ifdef __GNUC__ #ifdef BINARYNINJACORE_LIBRARY @@ -356,6 +356,12 @@ extern "C" AnalysisWarningLineType }; + enum BNTokenEscapingType + { + NoTokenEscapingType = 0, + BackticksTokenEscapingType = 1, + }; + enum BNAnalysisWarningActionType { NoAnalysisWarningAction = 0, @@ -4028,6 +4034,8 @@ extern "C" char** errors, BNQualifiedNameList* typesAllowRedefinition); BINARYNINJACOREAPI void BNFreeQualifiedNameAndType(BNQualifiedNameAndType* obj); BINARYNINJACOREAPI void BNFreeQualifiedNameAndTypeArray(BNQualifiedNameAndType* obj, size_t count); + BINARYNINJACOREAPI char* BNEscapeTypeName(const char* name, BNTokenEscapingType escaping); + BINARYNINJACOREAPI char* BNUnescapeTypeName(const char* name, BNTokenEscapingType escaping); BINARYNINJACOREAPI BNQualifiedNameAndType* BNGetAnalysisTypeList(BNBinaryView* view, size_t* count); BINARYNINJACOREAPI void BNFreeTypeList(BNQualifiedNameAndType* types, size_t count); @@ -4952,7 +4960,7 @@ extern "C" BNBoolWithConfidence* varArg, BNOffsetWithConfidence* stackAdjust); BINARYNINJACOREAPI BNType* BNNewTypeReference(BNType* type); BINARYNINJACOREAPI BNType* BNDuplicateType(BNType* type); - BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, BNQualifiedName* name); + BINARYNINJACOREAPI char* BNGetTypeAndName(BNType* type, BNQualifiedName* name, BNTokenEscapingType escaping); BINARYNINJACOREAPI void BNFreeType(BNType* type); BINARYNINJACOREAPI BNTypeBuilder* BNCreateTypeBuilderFromType(BNType* type); @@ -5012,15 +5020,15 @@ extern "C" BINARYNINJACOREAPI uint32_t BNTypeGetSystemCallNumber(BNType* type); BINARYNINJACOREAPI bool BNTypeIsSystemCall(BNType* type); - BINARYNINJACOREAPI char* BNGetTypeString(BNType* type, BNPlatform* platform); - BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type, BNPlatform* platform); - BINARYNINJACOREAPI char* BNGetTypeStringAfterName(BNType* type, BNPlatform* platform); + BINARYNINJACOREAPI char* BNGetTypeString(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping); + BINARYNINJACOREAPI char* BNGetTypeStringBeforeName(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping); + BINARYNINJACOREAPI char* BNGetTypeStringAfterName(BNType* type, BNPlatform* platform, BNTokenEscapingType escaping); BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokens( - BNType* type, BNPlatform* platform, uint8_t baseConfidence, size_t* count); + BNType* type, BNPlatform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping, size_t* count); BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokensBeforeName( - BNType* type, BNPlatform* platform, uint8_t baseConfidence, size_t* count); + BNType* type, BNPlatform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping, size_t* count); BINARYNINJACOREAPI BNInstructionTextToken* BNGetTypeTokensAfterName( - BNType* type, BNPlatform* platform, uint8_t baseConfidence, size_t* count); + BNType* type, BNPlatform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping, size_t* count); BINARYNINJACOREAPI BNType* BNTypeWithReplacedStructure(BNType* type, BNStructure* from, BNStructure* to); BINARYNINJACOREAPI BNType* BNTypeWithReplacedEnumeration(BNType* type, BNEnumeration* from, BNEnumeration* to); @@ -5029,7 +5037,7 @@ extern "C" BINARYNINJACOREAPI bool BNAddTypeMemberTokens(BNType* type, BNBinaryView* data, BNInstructionTextToken** tokens, size_t* tokenCount, int64_t offset, char*** nameList, size_t* nameCount, size_t size, bool indirect); - BINARYNINJACOREAPI BNTypeDefinitionLine* BNGetTypeLines(BNType* type, BNBinaryView* data, const char* name, int lineWidth, bool collapsed, size_t* count); + BINARYNINJACOREAPI BNTypeDefinitionLine* BNGetTypeLines(BNType* type, BNBinaryView* data, const char* name, int lineWidth, bool collapsed, BNTokenEscapingType escaping, size_t* count); BINARYNINJACOREAPI void BNFreeTypeDefinitionLineList(BNTypeDefinitionLine* list, size_t count); BINARYNINJACOREAPI BNQualifiedName BNTypeBuilderGetTypeName(BNTypeBuilder* nt); diff --git a/python/types.py b/python/types.py index 7538bcd5..b086ef78 100644 --- a/python/types.py +++ b/python/types.py @@ -28,7 +28,7 @@ from abc import abstractmethod from . import _binaryninjacore as core from .enums import ( StructureVariant, SymbolType, SymbolBinding, TypeClass, NamedTypeReferenceClass, ReferenceType, VariableSourceType, - TypeReferenceType, MemberAccess, MemberScope, TypeDefinitionLineType + TypeReferenceType, MemberAccess, MemberScope, TypeDefinitionLineType, TokenEscapingType ) from . import callingconvention from . import function as _function @@ -152,6 +152,14 @@ class QualifiedName: def name(self, value: List[str]) -> None: self._name = value + @staticmethod + def escape(name: str, escaping: TokenEscapingType) -> str: + return core.BNEscapeTypeName(name, escaping) + + @staticmethod + def unescape(name: str, escaping: TokenEscapingType) -> str: + return core.BNUnescapeTypeName(name, escaping) + @dataclass(frozen=True) class TypeReferenceSource: @@ -1503,10 +1511,7 @@ class Type: return f"<type: immutable:{self.type_class.name} '{self}'>" def __str__(self): - platform = None - if self._platform is not None: - platform = self._platform.handle - return core.BNGetTypeString(self._handle, platform) + return self.get_string() def __len__(self): return self.width @@ -1556,59 +1561,148 @@ class Type: type_conf.confidence = self.confidence return type_conf - def get_string_before_name(self) -> str: + def get_string( + self, escaping: TokenEscapingType = TokenEscapingType.NoTokenEscapingType + ) -> str: + """ + Get string representation for this type + :param TokenEscapingType escaping: How to escape non-parsable strings in types + :return: String for type + :rtype: str + :Example: + >>> Type.array(Type.int(4), 10).get_string() + 'int32_t[0xa]' + """ platform = None if self._platform is not None: platform = self._platform.handle - return core.BNGetTypeStringBeforeName(self._handle, platform) + return core.BNGetTypeString(self._handle, platform, escaping) - def get_string_after_name(self) -> str: + def get_string_before_name( + self, escaping: TokenEscapingType = TokenEscapingType.NoTokenEscapingType + ) -> str: + """ + Get the string to be printed before this type's name in a representation of it + :param TokenEscapingType escaping: How to escape non-parsable strings in types + :return: String for type representation before the name + :rtype: str + :Example: + >>> Type.array(Type.int(4), 10).get_string() + 'int32_t[0xa]' + >>> Type.array(Type.int(4), 10).get_string_before_name() + 'int32_t' + """ platform = None if self._platform is not None: platform = self._platform.handle - return core.BNGetTypeStringAfterName(self._handle, platform) + return core.BNGetTypeStringBeforeName(self._handle, platform, escaping) + + def get_string_after_name( + self, escaping: TokenEscapingType = TokenEscapingType.NoTokenEscapingType + ) -> str: + """ + Get the string to be printed after this type's name in a representation of it + :param TokenEscapingType escaping: How to escape non-parsable strings in types + :return: String for type representation after the name + :rtype: str + :Example: + >>> Type.array(Type.int(4), 10).get_string() + 'int32_t[0xa]' + >>> Type.array(Type.int(4), 10).get_string_after_name() + '[0xa]' + """ + platform = None + if self._platform is not None: + platform = self._platform.handle + return core.BNGetTypeStringAfterName(self._handle, platform, escaping) @property def tokens(self) -> List['_function.InstructionTextToken']: """Type string as a list of tokens (read-only)""" return self.get_tokens() - def get_tokens(self, base_confidence=core.max_confidence) -> List['_function.InstructionTextToken']: + def get_tokens( + self, base_confidence=core.max_confidence, + escaping: TokenEscapingType = TokenEscapingType.NoTokenEscapingType + ) -> List['_function.InstructionTextToken']: + """ + Get a list of tokens for the definition of a type + :param int base_confidence: Confidence of this type + :param TokenEscapingType escaping: How to escape non-parsable strings in types + :return: List of tokens + :rtype: List[_function.InstructionTextToken] + :Example: + >>> Type.array(Type.int(4), 10).get_string() + 'int32_t[0xa]' + >>> Type.array(Type.int(4), 10).get_tokens() + ['int32_t', ' ', '[', '0xa', ']'] + """ count = ctypes.c_ulonglong() platform = None if self._platform is not None: platform = self._platform.handle - tokens = core.BNGetTypeTokens(self._handle, platform, base_confidence, count) + tokens = core.BNGetTypeTokens(self._handle, platform, base_confidence, escaping, count) assert tokens is not None, "core.BNGetTypeTokens returned None" result = _function.InstructionTextToken._from_core_struct(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result - def get_tokens_before_name(self, base_confidence=core.max_confidence) -> List['_function.InstructionTextToken']: + def get_tokens_before_name( + self, base_confidence=core.max_confidence, + escaping: TokenEscapingType = TokenEscapingType.NoTokenEscapingType + ) -> List['_function.InstructionTextToken']: + """ + Get a list of tokens for the definition of a type that are placed before the type name + :param int base_confidence: Confidence of this type + :param TokenEscapingType escaping: How to escape non-parsable strings in types + :return: List of tokens + :rtype: List[_function.InstructionTextToken] + :Example: + >>> Type.array(Type.int(4), 10).get_string() + 'int32_t[0xa]' + >>> Type.array(Type.int(4), 10).get_tokens_before_name() + ['int32_t'] + """ count = ctypes.c_ulonglong() platform = None if self._platform is not None: platform = self._platform.handle - tokens = core.BNGetTypeTokensBeforeName(self._handle, platform, base_confidence, count) + tokens = core.BNGetTypeTokensBeforeName(self._handle, platform, base_confidence, escaping, count) assert tokens is not None, "core.BNGetTypeTokensBeforeName returned None" result = _function.InstructionTextToken._from_core_struct(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result - def get_tokens_after_name(self, base_confidence=core.max_confidence) -> List['_function.InstructionTextToken']: + def get_tokens_after_name( + self, base_confidence=core.max_confidence, + escaping: TokenEscapingType = TokenEscapingType.NoTokenEscapingType + ) -> List['_function.InstructionTextToken']: + """ + Get a list of tokens for the definition of a type that are placed after the type name + :param int base_confidence: Confidence of this type + :param TokenEscapingType escaping: How to escape non-parsable strings in types + :return: List of tokens + :rtype: List[_function.InstructionTextToken] + :Example: + >>> Type.array(Type.int(4), 10).get_string() + 'int32_t[0xa]' + >>> Type.array(Type.int(4), 10).get_tokens_after_name() + ['[', '0xa', ']'] + """ count = ctypes.c_ulonglong() platform = None if self._platform is not None: platform = self._platform.handle - tokens = core.BNGetTypeTokensAfterName(self._handle, platform, base_confidence, count) + tokens = core.BNGetTypeTokensAfterName(self._handle, platform, base_confidence, escaping, count) assert tokens is not None, "core.BNGetTypeTokensAfterName returned None" result = _function.InstructionTextToken._from_core_struct(tokens, count.value) core.BNFreeInstructionText(tokens, count.value) return result def get_lines( - self, bv: 'binaryview.BinaryView', name: str, line_width: int = 80, collapsed: bool = False + self, bv: 'binaryview.BinaryView', name: str, line_width: int = 80, collapsed: bool = False, + escaping: TokenEscapingType = TokenEscapingType.NoTokenEscapingType ) -> List['TypeDefinitionLine']: """ Get a list of :py:class:`TypeDefinitionLine` structures for representing a Type in a structured form. @@ -1619,11 +1713,12 @@ class Type: :param str name: Displayed name of the Type :param int line_width: Maximum width of lines (in characters) :param bool collapsed: If the type should be collapsed, and not show fields/members + :param TokenEscapingType escaping: How to escape non-parsable strings in types :return: Returns a list of :py:class:`TypeDefinitionLine` structures :rtype: :py:class:`TypeDefinitionLine` """ count = ctypes.c_ulonglong() - core_lines = core.BNGetTypeLines(self._handle, bv.handle, name, line_width, collapsed, count) + core_lines = core.BNGetTypeLines(self._handle, bv.handle, name, line_width, collapsed, escaping, count) assert core_lines is not None, "core.BNGetTypeLines returned None" lines = [] for i in range(count.value): diff --git a/rust/src/types.rs b/rust/src/types.rs index 102d064c..3afc9c9d 100644 --- a/rust/src/types.rs +++ b/rust/src/types.rs @@ -957,7 +957,7 @@ impl From<&TypeBuilder> for Ref<Type> { impl fmt::Display for Type { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", unsafe { - BnString::from_raw(BNGetTypeString(self.handle, ptr::null_mut())) + BnString::from_raw(BNGetTypeString(self.handle, ptr::null_mut(), BNTokenEscapingType::NoTokenEscapingType)) }) } } diff --git a/suite/api_test.py b/suite/api_test.py index d722012a..e7f6a325 100644 --- a/suite/api_test.py +++ b/suite/api_test.py @@ -11,7 +11,8 @@ from binaryninja.pluginmanager import RepositoryManager from binaryninja.platform import Platform from binaryninja.function import Function from binaryninja.enums import (StructureVariant, NamedTypeReferenceClass, MemberAccess, - MemberScope, ReferenceType, VariableSourceType, SymbolBinding, SymbolType) + MemberScope, ReferenceType, VariableSourceType, + SymbolBinding, SymbolType, TokenEscapingType) from binaryninja.types import (QualifiedName, Type, TypeBuilder, EnumerationMember, FunctionParameter, OffsetWithConfidence, BoolWithConfidence, EnumerationBuilder, NamedTypeReferenceBuilder, StructureBuilder, StructureMember, IntegerType, StructureType, Symbol, NameSpace, MutableTypeBuilder, NamedTypeReferenceType) @@ -502,6 +503,63 @@ class TypeParserTest(unittest.TestCase): for expect_offset, member in zip(member_offsets, s.members): assert member.offset == expect_offset, f"Structure member property: 'offset' {expect_offset} incorrect for {member.name} in {definition} got {member.offset} instead" + def test_escaping(self): + escaped = [ + ('test', 'test', 'test'), + ('a0b', 'a0b', 'a0b'), + ('a$b', 'a$b', 'a$b'), + ('a_b', 'a_b', 'a_b'), + ('a@b', 'a@b', 'a@b'), + ('a!b', 'a!b', 'a!b'), + ('0a', '0a', '`0a`'), + ('_a', '_a', '_a'), + ('$a', '$a', '$a'), + ('@a', '@a', '`@a`'), + ('!a', '!a', '`!a`'), + ('a::b', 'a::b', '`a::b`'), + ('a b', 'a b', '`a b`'), + ('a`b', 'a`b', '`a\\`b`'), + ('a\\b', 'a\\b', '`a\\\\b`'), + ('a\\`b', 'a\\`b', '`a\\\\\\`b`'), + ('a\\\\`b', 'a\\\\`b', '`a\\\\\\\\\\`b`'), + ] + for source, expect_none, expect_backticks in escaped: + got_none = QualifiedName.escape(source, TokenEscapingType.NoTokenEscapingType) + assert got_none == expect_none, f"Escape test of {source} NoTokenEscapingType got {got_none} expected {expect_none}" + got_backticks = QualifiedName.escape(source, TokenEscapingType.BackticksTokenEscapingType) + assert got_backticks == expect_backticks, f"Escape test of {source} BackticksTokenEscapingType got {got_backticks} expected {expect_backticks}" + + got_unesc = QualifiedName.unescape(got_backticks, TokenEscapingType.BackticksTokenEscapingType) + assert got_unesc == source, f"Escape test round trip for {source} got {got_unesc} from {got_backticks}, expected {source}" + + def test_escaped_parsing(self): + valid = r''' + typedef uint32_t `type name with space`; + typedef `type name with space` `another name`; + enum `space enum` + { + `space enum member 1` = 1, + `space enum member 2` = 2, + }; + struct `space struct` + { + `another name` `first member`; + `another name`* `second member`; + `another name` (*`third member`)(`another name` `argument name`); + }; + ''' + types = self.p.parse_types_from_source(valid) + assert types.types['type name with space'] == Type.int(4, False) + assert types.types['another name'].name == QualifiedName(['type name with space']), f"Expected typedef, got {types.types['another name']}" + assert len(types.types['space enum'].members) == 2 + assert len(types.types['space struct'].members) == 3 + assert types.types['space struct'].members[0].name == 'first member' + assert types.types['space struct'].members[1].name == 'second member' + assert types.types['space struct'].members[1].type.target.name == 'another name' + assert types.types['space struct'].members[2].name == 'third member' + assert len(types.types['space struct'].members[2].type.target.parameters) == 1 + assert types.types['space struct'].members[2].type.target.parameters[0].name == 'argument name' + class TestQualifiedName(unittest.TestCase): def test_constructors_and_equality(self): @@ -202,7 +202,7 @@ size_t NameList::StringSize() const } -string NameList::GetString() const +string NameList::GetString(BNTokenEscapingType escaping) const { bool first = true; string out; @@ -210,11 +210,11 @@ string NameList::GetString() const { if (!first) { - out += m_join + name; + out += m_join + EscapeTypeName(name, escaping); } else { - out += name; + out += EscapeTypeName(name, escaping); } if (name.length() != 0) first = false; @@ -223,6 +223,24 @@ string NameList::GetString() const } +std::string NameList::EscapeTypeName(const std::string& name, BNTokenEscapingType escaping) +{ + char* str = BNEscapeTypeName(name.c_str(), escaping); + std::string result(str); + BNFreeString(str); + return result; +} + + +std::string NameList::UnescapeTypeName(const std::string& name, BNTokenEscapingType escaping) +{ + char* str = BNUnescapeTypeName(name.c_str(), escaping); + std::string result(str); + BNFreeString(str); + return result; +} + + BNNameList NameList::GetAPIObject() const { BNNameList result; @@ -584,65 +602,65 @@ Confidence<int64_t> Type::GetStackAdjustment() const } -string Type::GetString(Platform* platform) const +string Type::GetString(Platform* platform, BNTokenEscapingType escaping) const { - char* str = BNGetTypeString(m_object, platform ? platform->GetObject() : nullptr); + char* str = BNGetTypeString(m_object, platform ? platform->GetObject() : nullptr, escaping); string result = str; BNFreeString(str); return result; } -string Type::GetTypeAndName(const QualifiedName& nameList) const +string Type::GetTypeAndName(const QualifiedName& nameList, BNTokenEscapingType escaping) const { BNQualifiedName name = nameList.GetAPIObject(); - char* outName = BNGetTypeAndName(m_object, &name); + char* outName = BNGetTypeAndName(m_object, &name, escaping); QualifiedName::FreeAPIObject(&name); return outName; } -string Type::GetStringBeforeName(Platform* platform) const +string Type::GetStringBeforeName(Platform* platform, BNTokenEscapingType escaping) const { - char* str = BNGetTypeStringBeforeName(m_object, platform ? platform->GetObject() : nullptr); + char* str = BNGetTypeStringBeforeName(m_object, platform ? platform->GetObject() : nullptr, escaping); string result = str; BNFreeString(str); return result; } -string Type::GetStringAfterName(Platform* platform) const +string Type::GetStringAfterName(Platform* platform, BNTokenEscapingType escaping) const { - char* str = BNGetTypeStringAfterName(m_object, platform ? platform->GetObject() : nullptr); + char* str = BNGetTypeStringAfterName(m_object, platform ? platform->GetObject() : nullptr, escaping); string result = str; BNFreeString(str); return result; } -vector<InstructionTextToken> Type::GetTokens(Platform* platform, uint8_t baseConfidence) const +vector<InstructionTextToken> Type::GetTokens(Platform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping) const { size_t count; BNInstructionTextToken* tokens = - BNGetTypeTokens(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, &count); + BNGetTypeTokens(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, escaping, &count); return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); } -vector<InstructionTextToken> Type::GetTokensBeforeName(Platform* platform, uint8_t baseConfidence) const +vector<InstructionTextToken> Type::GetTokensBeforeName(Platform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping) const { size_t count; BNInstructionTextToken* tokens = - BNGetTypeTokensBeforeName(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, &count); + BNGetTypeTokensBeforeName(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, escaping, &count); return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); } -vector<InstructionTextToken> Type::GetTokensAfterName(Platform* platform, uint8_t baseConfidence) const +vector<InstructionTextToken> Type::GetTokensAfterName(Platform* platform, uint8_t baseConfidence, BNTokenEscapingType escaping) const { size_t count; BNInstructionTextToken* tokens = - BNGetTypeTokensAfterName(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, &count); + BNGetTypeTokensAfterName(m_object, platform ? platform->GetObject() : nullptr, baseConfidence, escaping, &count); return InstructionTextToken::ConvertAndFreeInstructionTextTokenList(tokens, count); } @@ -1004,11 +1022,11 @@ bool Type::AddTypeMemberTokens(BinaryView* data, vector<InstructionTextToken>& t std::vector<TypeDefinitionLine> Type::GetLines(Ref<BinaryView> data, const std::string& name, - int lineWidth, bool collapsed) + int lineWidth, bool collapsed, BNTokenEscapingType escaping) { size_t count; BNTypeDefinitionLine* list = - BNGetTypeLines(m_object, data->m_object, name.c_str(), lineWidth, collapsed, &count); + BNGetTypeLines(m_object, data->m_object, name.c_str(), lineWidth, collapsed, escaping, &count); std::vector<TypeDefinitionLine> results; for (size_t i = 0; i < count; i++) |
