GP-4071 - Gnu Demangler - Fixed live lock when parsing a symbol with an array definition

This commit is contained in:
dragonmacher
2023-11-29 09:34:56 -05:00
parent ab831f73b3
commit f4aaa63986
2 changed files with 128 additions and 3 deletions
@@ -213,7 +213,7 @@ public class GnuDemanglerParser {
* {lambda(NS1::Class1 const&, int, int)#1} const&
* {lambda(auto:1&&)#1}<NS1::NS2>&&
*
* Pattern: [optional text] brace lambda([parameters])#digits brace [trailing text]
* Pattern: [optional text] { lambda([parameters])#digits } [trailing text]
*
* Parts:
* -full text without leading characters (capture group 1)
@@ -227,13 +227,24 @@ public class GnuDemanglerParser {
/*
* Sample: {unnamed type#1}
*
* Pattern: [optional text] brace unnamed type#digits brace
* Pattern: [optional text] { unnamed type#digits }
*
* Parts:
* -full text without leading characters (capture group 1)
*/
private static final Pattern UNNAMED_TYPE_PATTERN = Pattern.compile("(\\{unnamed type#\\d+})");
/**
* Sample: template parameter object for namespace::StringLiteral<38ul>{char [38]{(char)69, (char)101, ... }}
*
* Pattern: (text) { (array type) [size] { array contents } }
*
* Parts:
* -non-array definition prefix, which is the type (capture group 1)
*/
private static final Pattern ARRAY_DATA_PATTERN =
Pattern.compile("(.+)\\{(.+)\\[\\d*\\]\\{.*\\}\\}");
/*
* Sample: covariant return thunk to Foo::Bar::copy(Foo::CoolStructure*) const
*
@@ -412,6 +423,11 @@ public class GnuDemanglerParser {
return new TypeInfoNameHandler(demangled, TYPEINFO_NAME_FOR);
}
Matcher arrayMatcher = ARRAY_DATA_PATTERN.matcher(type);
if (arrayMatcher.matches()) {
return new ArrayHandler(demangled, prefix, type);
}
return new ItemInNamespaceHandler(demangled, prefix, type);
}
@@ -754,6 +770,14 @@ public class GnuDemanglerParser {
for (int i = 0; i < datatype.length(); ++i) {
char ch = datatype.charAt(i);
//
// Hack: Not sure what this is, but we have seen template parameter values that start
// with an '&'
//
if (ch == '&' && i == 0) {
continue; // for now, let the '&' through to be part of the name
}
if (!finishedName && isDataTypeNameCharacter(ch)) {
continue;
}
@@ -1492,6 +1516,52 @@ public class GnuDemanglerParser {
}
}
private class ArrayHandler extends SpecialPrefixHandler {
private String arrayType;
ArrayHandler(String demangled, String prefix, String item) {
super(demangled);
this.demangled = demangled;
this.prefix = prefix;
this.type = item;
//
// Handle array data definitions here for now. If we see this in non-specialized prefix
// cases, then we can extract this code.
//
Matcher arrayMatcher = ARRAY_DATA_PATTERN.matcher(type);
if (arrayMatcher.matches()) {
// keep only the type information, dropping the array definition
type = arrayMatcher.group(1);
arrayType = arrayMatcher.group(2).trim();
}
}
@Override
DemangledObject doBuild(Demangled namespace) {
DemangledObject demangledObject = parseItemInNamespace(type);
if (demangledObject instanceof DemangledVariable variable) {
//
// Creating a DemangledString here will correctly create the string data when this
// demangled type is applied.
//
if ("char".equals(arrayType) && type.contains("StringLiteral")) {
// treat a char[] as a string
DemangledString ds =
new DemangledString(variable.getMangledString(), demangled, type, type,
-1 /*unknown length*/, false);
ds.setSpecialPrefix(prefix);
return ds;
}
}
return demangledObject;
}
}
private class ThunkHandler extends SpecialPrefixHandler {
ThunkHandler(String demangled, String prefix, String item) {
@@ -2140,8 +2140,63 @@ public class GnuDemanglerParserTest extends AbstractGenericTest {
new DemangledDataType("fake", "fake", DemangledDataType.LONG_LONG).getDataType(null));
}
@Test
public void testTemplateParameterObectWithArrayDefinition() throws Exception {
//
// mangled: _ZTAXtlN9envHelper13StringLiteralILm38EEEtlA38_cLc67ELc111ELc114ELc101ELc65ELc117ELc100ELc105ELc111ELc95ELc67ELc97ELc112ELc116ELc117ELc114ELc101ELc67ELc111ELc110ELc118ELc101ELc114ELc116ELc101ELc114ELc67ELc104ELc97ELc105ELc110ELc95ELc73ELc110ELc112ELc117ELc116EEEE
//
// demangled: template parameter object for envHelper::StringLiteral<38ul>{char [38]{(char)67, (char)111, (char)114, (char)101, (char)65, (char)117, (char)100, (char)105, (char)111, (char)95, (char)67, (char)97, (char)112, (char)116, (char)117, (char)114, (char)101, (char)67, (char)111, (char)110, (char)118, (char)101, (char)114, (char)116, (char)101, (char)114, (char)67, (char)104, (char)97, (char)105, (char)110, (char)95, (char)73, (char)110, (char)112, (char)117, (char)116}}
//
// Note: this object ends in a char array definition:
//
// ...{char [38]{(char)67, .... }}
//
String mangled =
"_ZTAXtlN9envHelper13StringLiteralILm38EEEtlA38_cLc67ELc111ELc114ELc101ELc65ELc117ELc100ELc105ELc111ELc95ELc67ELc97ELc112ELc116ELc117ELc114ELc101ELc67ELc111ELc110ELc118ELc101ELc114ELc116ELc101ELc114ELc67ELc104ELc97ELc105ELc110ELc95ELc73ELc110ELc112ELc117ELc116EEEE";
String demangled = process.demangle(mangled);
DemangledObject object = parser.parse(mangled, demangled);
assertNotNull(object);
assertType(object, DemangledString.class);
String signature = object.getSignature(false);
assertEquals("template parameter object for envHelper::StringLiteral<38ul>", signature);
}
@Test
public void testAllocatorTraits_AlocateAtLeast() throws Exception {
//
// mangled: _ZNSt3__119__allocate_at_leastB7v160006INS_9allocatorINS_10unique_ptrIvN10applesauce4raii2v16detail23opaque_deletion_functorIPvXadL_Z27VPTimeFreqConverter_DisposeEEEEEEEEEENS_19__allocation_resultINS_16allocator_traitsIT_E7pointerEEERSE_m
//
// demangled: std::__1::__allocation_result<std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<void, applesauce::raii::v1::detail::opaque_deletion_functor<void*, &VPTimeFreqConverter_Dispose> > > >::pointer> std::__1::__allocate_at_least[abi:v160006]<std::__1::allocator<std::__1::unique_ptr<void, applesauce::raii::v1::detail::opaque_deletion_functor<void*, &VPTimeFreqConverter_Dispose> > > >(std::__1::allocator<std::__1::unique_ptr<void, applesauce::raii::v1::detail::opaque_deletion_functor<void*, &VPTimeFreqConverter_Dispose> > >&, unsigned long)
//
// Note: __allocate_at_least is a C++23 feature
//
String mangled =
"_ZNSt3__119__allocate_at_leastB7v160006INS_9allocatorINS_10unique_ptrIvN10applesauce4raii2v16detail23opaque_deletion_functorIPvXadL_Z27VPTimeFreqConverter_DisposeEEEEEEEEEENS_19__allocation_resultINS_16allocator_traitsIT_E7pointerEEERSE_m";
String demangled = process.demangle(mangled);
DemangledObject object = parser.parse(mangled, demangled);
assertNotNull(object);
assertType(object, DemangledFunction.class);
assertName(object,
"__allocate_at_least[abi:v160006]<std::__1::allocator<std::__1::unique_ptr<void,applesauce::raii::v1::detail::opaque_deletion_functor<void*,&VPTimeFreqConverter_Dispose>>>>",
"std",
"__1");
String signature = object.getSignature(false);
assertEquals(
"std::__1::__allocation_result<std::__1::allocator_traits<std::__1::allocator<std::__1::unique_ptr<void,applesauce::raii::v1::detail::opaque_deletion_functor<void*,&VPTimeFreqConverter_Dispose>>>>::pointer> std::__1::__allocate_at_least[abi:v160006]<std::__1::allocator<std::__1::unique_ptr<void,applesauce::raii::v1::detail::opaque_deletion_functor<void*,&VPTimeFreqConverter_Dispose>>>>(std::__1::allocator<std::__1::unique_ptr<void,applesauce::raii::v1::detail::opaque_deletion_functor<void *,&VPTimeFreqConverter_Dispose>>> &,unsigned long)",
signature);
}
private void assertType(Demangled o, Class<?> c) {
assertTrue("Wrong demangled type. " + "\nExpected " + c + "; " + "\nfound " + o.getClass(),
assertTrue("Wrong demangled type. \nExpected " + c + "; \nfound " + o.getClass(),
c.isInstance(o));
}