JDK-8191137 : keytool fails to format resource strings for keys for some languages after JDK-8171319
  • Type: Bug
  • Component: security-libs
  • Sub-Component: java.security
  • Affected Version: 8u151,9.0.1
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2017-11-13
  • Updated: 2018-02-15
  • Resolved: 2017-11-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10 JDK 7 JDK 8 JDK 9 Other
10 b32Fixed 7u171Fixed 8u161Fixed 9.0.4Fixed openjdk7uFixed
Related Reports
Blocks :  
Duplicate :  
Relates :  
Description
JDK-8171319 introduced the following code:

    private String withWeak(PublicKey key) {
        if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
            return String.format(rb.getString("key.bit"),
                    KeyUtil.getKeySize(key), key.getAlgorithm());
        } else {
            return String.format(rb.getString("key.bit.weak"),
                    KeyUtil.getKeySize(key), key.getAlgorithm());
        }
    }

That is the format is determined by rb.getString("key.bit.weak") or rb.getString("key.bit"). For example for -Duser.language=en, these formats are:

 %d-bit %s key

and

 %d-bit %s key (weak)

Thus, in English this expects an integer as first argument and a String as the second. In some languages however, the formats returned by  rb.getString("key.bit.weak") and rb.getString("key.bit") return different format strings: E.g. String and then Integer in French or Spanish.

Attached is a simple reproducer. It fails with -Duser.language=es with:

$ javac TestKeyTool
$ java -Duser.language=es TestKeyTool
DEBUG: Format is: Clave %s de %d bits (d��bil)
Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.String
	at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302)
	at java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2793)
	at java.util.Formatter$FormatSpecifier.print(Formatter.java:2747)
	at java.util.Formatter.format(Formatter.java:2520)
	at java.util.Formatter.format(Formatter.java:2455)
	at java.lang.String.format(String.java:2940)
	at TestKeyTool.main(TestKeyTool.java:11)

Expected:
Ordering of format is the same as in English: Integer then String. For example in English the reproducer prints:

$ java -Duser.language=en TestKeyTool
DEBUG: Format is: %d-bit %s key (weak)
23-bit foo key (weak)
DEBUG: Format is: %d-bit %s key
23-bit foo key
Comments
Add associated bug for localized fix
24-11-2017

Can we add the CR template please?
22-11-2017

What's the bug/subtask with the actual fix?
15-11-2017

Please note that this fix does not introduce any behavior change and a real fix on the French translation will be in another bug.
14-11-2017

Sure, I'll take back this bug and make changes in English first.
14-11-2017

I suggest to update the English resource message first, then the localized message would keep the position of the parameters.
14-11-2017

If the language has a different ordering, it should be numbered. For example, "Clave %2$s de %1$d bits (d��bil)", and Java will know substitute %1$d with the 1st argument and %2$s with the 2nd one.
13-11-2017

Changing the bug summary should change since the key does not have to be weak for the issue to occur.
13-11-2017

openjdk9-2017-11-13-9.0.1/bin/java -Duser.language=es TestKeyTool DEBUG: Format is: Clave %s de %d bits (d��bil) Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.String at java.base/java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4331) at java.base/java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2846) at java.base/java.util.Formatter$FormatSpecifier.print(Formatter.java:2800) at java.base/java.util.Formatter.format(Formatter.java:2581) at java.base/java.util.Formatter.format(Formatter.java:2517) at java.base/java.lang.String.format(String.java:2747) at TestKeyTool.main(TestKeyTool.java:14)
13-11-2017

I should note that this issue can cause keytool to fail to import/list/etc since printing the warning throws an exception. Examples: https://stackoverflow.com/questions/46958548/im-having-trouble-getting-sha1-certificate-with-keytool https://stackoverflow.com/questions/47134165/keytool-import-certificate-java-util-illegalformatconversionexception-in-linux
13-11-2017