You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@commons.apache.org by "Christian Kleinbölting (Jira)" <ji...@apache.org> on 2020/01/26 08:48:00 UTC
[jira] [Resolved] (CODEC-279) Base64.decode fails on Java11 for
certain valid base 64 encoded String
[ https://issues.apache.org/jira/browse/CODEC-279?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Christian Kleinbölting resolved CODEC-279.
------------------------------------------
Resolution: Fixed
[~aherbert] Thank you for the though investigation and explanation.
I complete agree with you assement and found that replacing the last character as you have proposed fixed the problem with versions 1.13 and 1.15 for me and also results in the same bytes as returned by the java.util Decoder.
[~michael-o] To answer your question: If I would disclose the String it would not be a secret anymore and that is why I don't.
> Base64.decode fails on Java11 for certain valid base 64 encoded String
> ----------------------------------------------------------------------
>
> Key: CODEC-279
> URL: https://issues.apache.org/jira/browse/CODEC-279
> Project: Commons Codec
> Issue Type: Bug
> Affects Versions: 1.13, 1.14
> Environment: Java 11
> Reporter: Christian Kleinbölting
> Priority: Major
>
> The following lines will fail for a specific String:
> {code:java}
> String sharedSecret = "cannot_share_the_affected_string_because_it_is_a_secret";
> byte[] bytes = org.apache.commons.codec.binary.Base64.decodeBase64(sharedSecret); {code}
> The exception I get is
> {code:java}
> java.lang.IllegalArgumentException: Last encoded character (before the paddings if any) is a valid base 64 alphabet but not a possible value at org.apache.commons.codec.binary.Base64.validateCharacter(Base64.java:798)
> at org.apache.commons.codec.binary.Base64.decode(Base64.java:472)
> at org.apache.commons.codec.binary.BaseNCodec.decode(BaseNCodec.java:412)
> at org.apache.commons.codec.binary.BaseNCodec.decode(BaseNCodec.java:395)
> at org.apache.commons.codec.binary.Base64.decodeBase64(Base64.java:694)
> at com.rbmhtechnology.oidc.provider.spi.grants.jwt.thirdparty.rest.FooTest.foo(FooTest.java:17)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.base/java.lang.reflect.Method.invoke(Method.java:566)
> at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
> at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
> at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
> at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
> at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
> at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
> at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
> at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
> at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
> at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
> at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
> at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
> at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
> at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
> at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
> at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
> at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
> at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
> at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
> at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
> at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
> at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
> at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
> at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
> at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
> at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
> at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
> at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
> at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
> at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)Process finished with exit code 255
> {code}
> Using Java 11 (AdoptOpenJDK 13.0.1.hs-adpt). The same code will pass with Java 8 (AdoptOpenJDK 8.0.232.hs-adpt) and return the expected bytes.
> Unfortunately I was not able to construct another String which will make these lines throw an exception other than the String I have and that is a secret I cannot share. {{java.util.Base64.getDecoder().decode(String)}} is able to decode the affected String though.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)