-
Notifications
You must be signed in to change notification settings - Fork 36
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
Stack overflow demangling symbol #165
Comments
Unfortunately the panic handler can't catch this. |
This is from a Mozilla-built
|
There's an infinite recursion of course:
|
Whether or not this symbol is valid per spec, |
Maybe the way this is supposed to work is that we can't parse a mangled name into a substitution loop... I see that |
Here's what that gets parsed into: |
IIRC, we used to disallow substitution reference cycles, but @khuey found a symbol that required a limited form of that to correctly demangle(!!) We have the recursion limit which can be set conservatively, and this should catch this sort of bug, but it (a) might itself be incomplete, and (b) is not "automatic" in that it requires some thinking/adjusting/tweaking/checking on the users part. Would be happy to see this story improve! |
Relevant part:
|
The main AST is
Non-substitution 7 is
so guess that's our loop; template parameter 0 is being resolved to that BackReference. |
I'm not sure yet but I suspect the problem is that the template parameter 0 in substitution 21 is looked up in the context of the use of substitution 21, not where substitution 21 first occurred. Is this a fundamental design issue in cpp_demangle or am I misunderstanding the code? |
Here's a trivial example that causes cpp_demangle to overflow the stack: when the template parameter just refers to itself: |
I filed itanium-cxx-abi/cxx-abi#68 on the ambiguity about how template parameter references in substitutions are resolved. |
Leaving aside that issue for now, I think the main problem here is that there's nothing preventing loops in template argument references. |
One possible approach would be to have a table on the side, in DemangleContext I guess, to detect when we form a cycle through a TemplateParam. Another possible approach would be to bring template parameters into scope one at a time during demangling, only after we've demangled it. Though this comment makes me wonder if that would actually be correct:
Another possible approach would be to validate template parameter references as we parse, and return a parse error if there is a reference to a parameter we haven't completely parsed. But again that might not actually be correct. Also that would only work if the spec ambiguity issue was resolved to say that template parameter references in substitutions reference the template instance where they are defined. |
Maybe it would be enough to track in the DemangleContext the index of the template parameter, if any, we are currently demangling. If we see a template parameter reference >= the current index, we fail or print a placeholder. I think that will prevent template-parameter-only loops. |
Cast operators are the edge case, yes. They might break the index checking you describe. If so, I think we can maintain a bit set for template parameters, and whenever we enter demangling of a template parameter, we check if its bit is set. If the bit is set, that is a recursion error, otherwise we set the bit, demangle the parameter, and then unset the bit on exit. |
My patch causes failures in tests I don't understand. For example:
I don't understand the |
No, it seems that template parameter references in g's template parameter list always look outside that scope... |
I solved the problem by tracking which |
The text was updated successfully, but these errors were encountered: