Hi Eric!
I just hit this one -- I consider it a regression from 5.2.1 (caused by the bugfix to avoid clashes with library entries); it's trappy and causes runtime errors for me, but arguably could be not a bug, but a feature... :)
So the problem is this. When you apply an existing obfuscation mapping it only considers those entries it physically "sees" on library path (or class path). My obfuscated library A included third party library B and while A was on final librarypath, B wasn't; because I used package remapping and certain classes did use the same package, the class names in the emitted obfuscated code clashed with library B's obfuscated classes in (A+B) obfuscated library...
This sounds more complex than it is -- I attach a simple reproduce code.
A fix can be twofold -- either warn about existing mappings (of non-present classes) that conflict with the output or (to me a better solution) -- reserve and exclude all class names provided in applymapping. Sure, this can be abused a bit (to exclude certain names), but I think it's a safer solution than warnings alone.
Just a quick follow-up. The same effect can actually happen in a different scenario as well - when proguard "shrinks" the set of library classes prior to obfuscation and discards certain classes (that used a mapping which eventually overlaps with the input classes).
Thanks for your report, Dawid. Applying mapping files can introduce many conflicts if the processed code has changed significantly, so I don't recommend using the option. I'm afraid this will have a low priority for now.
Hi Eric. It's not really the case here -- the code hasn't changed at all, it's just missing some library classes that were used during the original obfuscation. The particular scenario we're using it in is this: we obfuscate the production library code and then obfuscate the tests for this library with the produced mapping. This way we can run the original set of tests against the obfuscated final jar, which is quite handy to capture problems with obfuscation itself early (and other issues as well). I don't see how we could do it without the trick of the mapping file.
Forget about that though -- the core of the issue is that the mapping file's entries that do not occur on the input can end up being ignored. This, I think, is trappy. If you provide a mapping file with a->b then my expectation would be that even if class a doesn't exist on input, b wouldn't be used as an obfuscated target for any of the existing classes. This is the issue and concern I wanted to convey here.
This said, I agree it's probably very low-priority as it requires a certain set of conditions to occur and is an advanced use case for proguard. I can patch proguard locally (thanks again for making the code public) or I can fix our build setup to include all the classpath entries in both cases.
Hi Eric. I had to go back to this issue -- it's still not working in PG 6.1.1. I think it's a bug and it's also easily prevented -- see the patch here.
https://github.com/dweiss/proguard/commit/6e729028a0c440dce90a40dc80137463a8c0fbef
Here is another repro for the same problem.