Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java, why does WindowsPreferences use slashes for capital letters?

I've been working with the java.util.prefs.Preferences functionality (in Java 8, on a Windows machine). And it works, where I can write new keys to the Windows Registry. So, I use Preferences.systemRoot() to get the Preferences object for the system, and then use the node() method to get a Preferences object that maps to a node in the Windows Registry. And it's creating things fine.

The Key I'm using for the Node is a String in all capital letters ("RBI"). When I look at the node in the Windows Registry, it comes up as "/R/B/I", with forward slashes in the name.

I thought this was odd, so I've dug around a bit And it looks like this is intentional. I found the class that provides the implementation of Preferences on a Windows environment (java.util.prefs.WindowsPreferences) and the method is uses for building the values sent to the windows registry is a static method toWindowsName. In the JavaDoc for that....

/**
 * Converts value's or node's name to its Windows representation
 * as a byte-encoded string.
 * Two encodings, simple and altBase64 are used.
 * <p>
 * <i>Simple</i> encoding is used, if java string does not contain
 * any characters less, than 0x0020, or greater, than 0x007f.
 * Simple encoding adds "/" character to capital letters, i.e.
 * "A" is encoded as "/A". Character '\' is encoded as '//',
 * '/' is encoded as '\'.
 * The constructed string is converted to byte array by truncating the
 * highest byte and adding the terminating <tt>null</tt> character.
 * <p>
 * <i>altBase64</i>  encoding is used, if java string does contain at least
 * one character less, than 0x0020, or greater, than 0x007f.
 * This encoding is marked by setting first two bytes of the
 * Windows string to '/!'. The java name is then encoded using
 * byteArrayToAltBase64() method from
 * Base64 class.
 */

So, the Simple encoding will, for capital letters, add a forward slash.

Does anyone know why this is required? I had thought that the Registry could handle case-sensitive values, but this seems to indicate that it can't?

I can work around this, I'm just curious why this was done.

like image 843
EdH Avatar asked Apr 10 '14 23:04

EdH


1 Answers

I was curious as you and I found the following explanation:

Registry-Keys are case-preserving, but case-insensitive. For example if you have a key "Rbi" you cant make another key named "RBi". The case is saved but ignored. Sun's solution for case-sensitivity was to add slashes to the key.

Registry-Values are case-sensitive (and, of course, case-preserving). I don't think it was Sun's intention to add the slashes to the values as well, but somehow it slipped into the code. It seems to me, that this bug wasn't found for a long time. When the bug was discovered, many systems already depended on the wrong implementation, so they never removed it to retain compatibility.

If you don't like the slashes in your Registry-Values, you may be interested in this implementation.

like image 142
MyPasswordIsLasercats Avatar answered Oct 21 '22 03:10

MyPasswordIsLasercats