Hacker News new | ask | show | jobs
by rianmcguire 1634 days ago
Revenge of the Titans is using the java.util.prefs.Preferences class from the Java standard library.

Looking at the implementation here: https://github.com/openjdk/jdk/blob/4f607f2adac3798c16a62e90...

If the requested directory name has certain "inappropriate" characters in it, it'll encode it using Base64.byteArrayToAltBase64, which is a non-standard base64 encoding using the alphabet defined here: https://github.com/openjdk/jdk/blob/4f607f2adac3798c16a62e90...

If we decode the directory name using that alphabet: https://gchq.github.io/CyberChef/#recipe=From_Base64('!%22%2...

You can see that it was encoding the text:

  slots_1.80
Nothing to see here, other than some sloppy filename handling in Déjà Dup.
2 comments

Hey, thanks so much for taking the time to do a deep dive. I'll file a bug report with the Déjà Dup devs.

If you don't mind me picking your brain: The logic behind isDirChar and dirName is not obvious to me. I understand not wanting to have a forward slash in your directory name, but the dirName function runs contrary to the goal of the isDirChar function (which in theory is stated as wanting to avoid special characters like a dot or an underscore, but it actually ends up letting through the dot, the underscore, and a lot of other characters). Or, am I reading the comments and the code wrong?

P.S. A minor observation; the alphabet on the URL has a slight typo (a backslash instead of a single quote, as one of the listed chars is an escaped quote):

  !"#$%&'(),-.:;<>@[]^`_{|}~abcdefghijklmnopqrstuvwxyz0123456789+?
instead of:

  !"#$%&\(),-.:;<>@[]^`_{|}~abcdefghijklmnopqrstuvwxyz0123456789+?
I think your reading of the code is fine - it's not entirely logical.

* Avoiding '.', but using it in the encoding doesn't make any sense, although I'm not sure there was a good reason to avoid it in the first place.

* Avoiding '_' but still using it is somewhat reasonable, because it's used as the sigil to mark the names as alt-base64 encoded.

* The alt-base64 encoding goes out of its way handle case folding (which is a real issue on Windows and macOS) - but the same issue can occur with the unencoded names too, and that's not handled.

* isDirChar permits characters that aren't valid on all platforms, like backslash on Windows.

The Preferences class was introduced in Java 1.4 according to the docs, and there's a bug report[1] referencing the encoding behaviour in the 1.4.0 release, so it's probably been like this since the initial implementation.

> P.S. A minor observation; the alphabet on the URL has a slight typo

Bad search-and-replace. Oops :)

[1] https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4696941

Nice! I was trying to figure out what the encoding was!

What’s the thinking behind a base64 encoding with double quotes?

Edit: “It is designed for use in environments where "case folding" occurs.”

That explains all the punctuation marks.

Still stupid. Directory names are not known for case folding.

Indeed. I was thinking that maybe it was trying to be compatible with WIN32 apps or something, but it seems that it's running against MS's conventions [0].

[0]: https://docs.microsoft.com/en-us/windows/win32/fileio/naming...