-
-
Notifications
You must be signed in to change notification settings - Fork 255
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
Add obfuscation on Enum type and Enum elements #80
Conversation
Hey hwdavr! While enum obfuscation works, the reason we don't do it is because some enum elements aren't meant to be obfuscated (like CodingKeys)... The project will build, but it will break parsing of these properties. The same reason for instance properties since changing their names would break Codable classes 😢 |
I agree that case like CodingKeys, shouldn't be obfuscated, but some enum type not used for CodingKeys still worth to obfuscate. Maybe we should has some options to filter out certain classes, like ProGuard in Android. |
I don't remember the full context of why I haven't done this, but I think it was very hard to automatically determine if an enum was used as the CodingKeys. |
I know it's difficult to determine automatically, but when we use Proguard in Android, it also has the similar issue. In Proguard, you have to keep those enum classes if you are going to serialise them. PPiOS-Rename also provides a option '-F' to filter out some classes. I think it's a common practice to exclude those Codable classes, rather than keeping everything even not related to Codable. |
Hmmm we could automatically ignore everything that has CodingKeys in the name, as I think I've never seen someone use a different naming convention for it :) With that, we probably wouldn't need an argument for ignoring additional names and the issue would be pretty much solved |
CodingKeys is only used when they what to choose different name from the property name, what if they don't implement CodingKeys at all, just use default names. And how do you prevent from obfuscating struct extending from Codable? |
I think there are two cases: 1 - When the compiler synthesizes the Codable implementation We don't need to worry about 1 because the lack of a declaration will prevent us from obfuscating it. For 2, there will be an explicit CodingKeys declaration which we shouldn't obfuscate. Since I'm not sure if we can easily determine if the enum inherits from CodingKeys, we could just grab the name and determine from there (like not obfuscating I think this covers structs that extend from Codable, is there something else that comes to your mind? |
Let's have one example to make sure my understanding is correct.
|
That's right, the name of the struct itself is irrelevant. We would need to recognize the struct itself if we obfuscated properties, which we dont because of other SourceKit bugs. |
Apologies, we don't obfuscate properties precisely because of Codable — if we can recognize that a struct inherits from Codable, then we can activate these as well. But in this case of the enum the name of the type doesn't matter, yes. |
OK, I will filter out enum with ending with |
Hi @rockbruno, I've commit the change for filtering out |
|
||
if type == .enum && name.hasSuffix("CodingKeys") { | ||
obfuscationData.excludedEnums.insert(usr) | ||
return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should do this when we're filling the declarations data, otherwise if the enumelement gets referenced before the declaration they are going to be wrongly obfuscated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I see. I will update it.
// Enum element belongs to excluded enum | ||
if usr.hasPrefix(exclusion) { | ||
return | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Iterating every single excluded enum sounds unnecessary, since we're checking for a prefix can't we just remove the suffix and check if the remainder exists in the set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know the mangled name rules for Swift.
For the below example of enum element "firstName", I need to make sure I can remove the suffix "9firstNameyA2FmF" from "s:14SwiftShieldSDK6PersonC17_personCodingKeys33_7242533BA8890D95B0EE7BCC963FFFCBLLO9firstNameyA2FmF" correctly, but from what I know, the mangled name rules keeping change for different Swift version.
Found declaration of _personCodingKeys (s:14SwiftShieldSDK6PersonC17_personCodingKeys33_7242533BA8890D95B0EE7BCC963FFFCBLLO)
Found declaration of firstName (s:14SwiftShieldSDK6PersonC17_personCodingKeys33_7242533BA8890D95B0EE7BCC963FFFCBLLO9firstNameyA2FmF)
Found declaration of lastName (s:14SwiftShieldSDK6PersonC17_personCodingKeys33_7242533BA8890D95B0EE7BCC963FFFCBLLO8lastNameyA2FmF)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was hoping that the number that comes before the name of the element was going to be constant... In that case, you could strip everything after the name of the enumelement
Let's try stripping everything after the last underline... I suppose that's harder to change but yeah, we might have problems with other Swift versions indeed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just commit a new change based on your idea.
let kind = data.kind | ||
|
||
if let type = self.sourceKit.referenceType(kind: kind), type == .enum && name.hasSuffix("CodingKeys") { | ||
obfuscationData.excludedEnums.insert(self.usrWithoutSuffix(usr)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything looks good now, but I'm just wondering if we need to do self.usrWithoutSuffix(usr)
here. The enum usr is already the stripped one, isn't it?
No, the enum class also has the a random hex string in the end, check this "s:14SwiftShieldSDK6PersonC17_personCodingKeys33_7242533BA8890D95B0EE7BCC963FFFCBLLO". |
Thanks! |
For this PR, it adds the support for enum type and enum elements.