Hacker News new | past | comments | ask | show | jobs | submit login
Android Studio’s “Code contains easter egg” inspection (2019) (wh0.github.io)
141 points by mqus on Nov 1, 2022 | hide | past | favorite | 42 comments



I do think that "Face Screaming in Fear" is indeed the only appropriate reaction to a compiler parsing escape sequences outside of character/string literals.

Also, it seems strange to add a detector for this specific case instead of actually fixing the IDE's parser to match the language's correct syntax rules.


The fact that Java allows and parses Unicode escapes just everywhere in source is a real surprise. That it's the same syntax you see other languages use for string-literal-only escapes and it's the same as Java's own other character literal sequences really adds to the surprise.

Is there any non-sneaky usage of this feature out there in the world? I suppose given the massive amount of Java, there probably is.


When Java was introduced many text editors did not support unicode directly. Escapes allows you to use unicode identifiers with an ascii-only editor. You probably wouldnt want to define you own non-ascii identfiers, but a third-party library might have them.


You can escape identifiers in JS, too. But what you can't do is escape just _any_ source character like the way it's defined in Java and used in the example. Writing `foo = \u0022bar\u0022`, for example, is invalid.


Fixing the parser as in properly switching back from comment coloring to code coloring? Won't tell you anything unless you look, and you might still miss it. The linter will ring alarm bells that someone is trying to hide code even if you never had the file in question on the screen.

I feel tempted to bring up the counter argument "but someone should look at untrusted code thoroughly enough to not miss it anyways!", but that would be like abolishing safety belts and airbags because surely people would drive more safely.


The only reason why this makes any sense as a threat vector is because Java code highlighting parsers and javac work differently. Sure, someone can still try it, but if they knew that every code highlighter would render it correctly they wouldn't bother.


I'd assume that there are plenty of editors that just do general C-style comment highlighting without diving into java-specific Unicode escapes. As long as you can't be sure that no bad actor could ever consider this obfuscation a net positive for their goals, the lint approach remains worthwhile. Worthwhile because its cost is so low.


True. I'm not saying the lint is a bad idea, just that fixing the parser is a better one.


My understanding is that the highlighting parser _is_ fixed to intentionally mis-parse to guarantee reasonable runtime complexity, and the lint check is a band-aid on top of it for a common type of adversarial input.

If you do the full parse you can end up with adversarial inputs that result in cubic or exponential run-time complexity (see, for example, Pygments CVEs for comparable examples in this domain).


Correct handling of Unicode escape sequences isn't something that's going to increase time complexity to cubic-or-more.


Maybe jetbrains didn't want to fix the IDE parser for some reason? Although there's still value to that lint warning as lint isn't coupled to the IDE. So you'd get value out of that warning regardless of if you're using Android Studio or not, as well as value in CI or similar.


Android Studio is a fork of IntelliJ, Google don't seem to contribute much stuff upstream in general. It seems to be more like, JetBrains pull from them sometimes when it's possible.


I'm guessing it's because handling escape sequences like these would have to be done in a separate pass over the source code. The escape sequence could be part of a separate token so you need to first resolve these escape sequences and then do tokenizing.


And is also the appropriate reaction to using Android Studio.


I see you didn't use the Eclipse plugin (with Ant scripts, yay!).

Dang I'm old.


Why would they use "Easter Egg" to describe "lightly obfuscated code"? They are two different things. Easter Eggs have no special need for obfuscation in source code, just in UI.

Especially for Java, not JavaScript where source code is at least slightly relevant to the end user experience?


Because frequently Easter eggs are frowned upon at large companies and I suppose developers may still be trying to sneak them in by obfuscation. So this linter is trying to catch those cases


Historically, Easter eggs were implemented as a way of having a verifiable resume. To reduce employee bargaining power, companies didn't include developer names in software credits. So even if you worked on project X, even if you designed and wrote the entire program as was common at the time, the developer didn't have any proof they could use on their resume. But, if you sneak in an Easter Egg, especially one that displays your name, you could use that as proof.

So, given the antagonistic relationship in which Easter Eggs originated, I'm not surprised that large companies would continue that antagonistic relationship.

Source: https://en.wikipedia.org/wiki/Easter_egg_(media)#Origin


I stuck difficult-to-find easter eggs in my game cartridges precisely because I wanted to prove that I'd written them. The eggs are not spectacular, nor do they subtract from the player experience. It was just signing my name, when I wasn't allowed to.

https://kotaku.com/donkey-kong-easter-egg-discovered-26-year...


In Japan, game companies forbade programmers from putting their real names in their games. It was an anti-poaching move, the studios didn't want their programmers hired out from under them.

So the game programmers put aliases in instead. Hence why you see such strange names in games like Yu2, Nakazoo, Faw, S.Miyahon (who is actually Shigeru Miyamoto), etc.


Your source points out while the term "Easter egg" was coined to describe a circumstance you mentioned, the concept is older, and used for circumstances other than what you described.


And we all know that the first and original use of a word is the only correct use of the word.


Realistically this would be the best way to get your easter egg caught.

Unicode escape characters in comments will draw most people's eyes immediately, it just doesn't look natural.

Instead write the easter egg in completely plain sight attached to a boring change, make sure the PR is passing CI on the first try, and a reviewer will skim for exactly .5 seconds before replying "LGTM!".


For better effect, put the easter egg in a file and directory starting with "z" so it appears last in the pull request.


People usually scroll straight down, so their eyes will dwell on the last contents

Just past the fold at the top, but out of view from the bottom, would be the ideal place


zlib-interface: contains functions for displaying the author's name.


It seems like it could be a way to draw attention to potentially concealed code without making an inflammatory and possibly false accusation. Or it could just be that someone at JetBrains used this trick to hide an Easter Egg at some point.


Probably because it's not looking for lightly obfuscated code, it's looking for hidden code (hidden by a unicode escape sequence).



There is also a constant named "DISALLOW_FUN" [1]. Probably intended for corporate devices.

[1] https://developer.android.com/reference/android/os/UserManag...


Apparently that user restriction is actually tested in two places in the codebase. Having the restiction on your user will prevent access to the Android version easter egg. It will also prevent access to debug features in whatever "DocumentUI" is.

I suppose third party apps could also test for it, and do things with it, but is is really just intended as a joke.


Nice!


"Used to determine whether the user making this call is subject to teleportations."

As a non-android developer, I am now more confused.


It's a reference to a very old (and since removed, at least in my version) Chrome Easter egg where Chrome Task Manager had a hidden column called "Goats Teleported".

See https://bugs.chromium.org/p/chromium/issues/detail?id=31482


Actually both are references to a very old game (Castlevania), which contained the mythical Goat Teleporter. It became a sort of internal Google meme/in-joke used whenever you needed some arbitrary object in an example. Goat teleporters show up in a few places in Google-external material, not just Chrome and Android. I recall them being occasionally mentioned when I worked there too, though it's been many years and I forget exactly how it got started.

https://gamefaqs.gamespot.com/ps/196885-castlevania-symphony...

If you search for it you'll find all the references are by Google except one or two (which are probably ex-googlers repeating the meme):

https://www.google.com/search?q=%22goat+teleporter%22


I'm pretty sure it used to return true if the user had Goat Simulator installed. Never played the game but I'm assuming there's something to do with teleportation in it.


Yeah, it did O.o

  2249  public boolean isUserAGoat() {
  2250     if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
  2251        return false;
  2252     }
  2253     // Caution: This is NOT @UserHandleAware (because mContext is getApplicationContext and
  2254     // can hold a different userId), but for R+ it returns false, so it doesn't matter anyway.
  2255     return mContext.getPackageManager()
  2256        .isPackageAvailable("com.coffeestainstudios.goatsimulator");
  2257  }
https://cs.android.com/android/platform/superproject/+/maste...


As a chromium task manager, I count teleported goats.


Wasn't there a function like, "isUserAMonkey()"? I recall seeing that years ago and got a chuckle out of it, but that reference doesn't include the function call.


Yea there is that method. I think it has something to do with chaos monkey testing or some sort.


This reminds me a bit of the "Trojan Source" paper.

https://trojansource.codes/


Is this inspection an easter egg itself?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: