From 2c0d50e63a3897781e770ecabc563c849d6b7489 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Mon, 4 Jan 2016 18:26:04 +0100 Subject: [PATCH] [util] decoding non-padded Base64 strings (EA-77396) --- .../util-rt/src/com/intellij/util/Base64.java | 10 +++-- .../testSrc/com/intellij/util/Base64Test.java | 45 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 platform/util/testSrc/com/intellij/util/Base64Test.java diff --git a/platform/util-rt/src/com/intellij/util/Base64.java b/platform/util-rt/src/com/intellij/util/Base64.java index 1893566eaa6e..8b2e9725d128 100644 --- a/platform/util-rt/src/com/intellij/util/Base64.java +++ b/platform/util-rt/src/com/intellij/util/Base64.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,7 +53,7 @@ public class Base64 { return ac; } - private static char getChar( int i) { + private static char getChar(int i) { if (i >= 0 && i <= 25) return (char)(65 + i); if (i >= 26 && i <= 51) return (char)(97 + (i - 26)); if (i >= 52 && i <= 61) return (char)(48 + (i - 52)); @@ -73,10 +73,12 @@ public class Base64 { byte[] raw = new byte[len]; int l = 0; for (int i1 = 0; i1 < s.length(); i1 += 4) { + int n = s.length() - i1; + if (n == 1) throw new IllegalArgumentException("Invalid Base64 string"); int j1 = (getValue(s.charAt(i1)) << 18) + (getValue(s.charAt(i1 + 1)) << 12) + - (getValue(s.charAt(i1 + 2)) << 6) + - (getValue(s.charAt(i1 + 3))); + (n > 2 ? (getValue(s.charAt(i1 + 2)) << 6) : 0) + + (n > 3 ? (getValue(s.charAt(i1 + 3))) : 0); for (int k = 0; k < 3 && l + k < raw.length; k++) { raw[l + k] = (byte)(j1 >> 8 * (2 - k) & 0xff); } diff --git a/platform/util/testSrc/com/intellij/util/Base64Test.java b/platform/util/testSrc/com/intellij/util/Base64Test.java new file mode 100644 index 000000000000..89c878fb9442 --- /dev/null +++ b/platform/util/testSrc/com/intellij/util/Base64Test.java @@ -0,0 +1,45 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.util; + +import org.junit.Test; + +import java.nio.charset.Charset; + +import static org.junit.Assert.assertEquals; + +@SuppressWarnings("SpellCheckingInspection") +public class Base64Test { + private static final Charset UTF8 = Charset.forName("UTF-8"); + + @Test + public void decodePadded() { + decode("YW55IGNhcm5hbCBwbGVhcw==", "any carnal pleas"); + decode("YW55IGNhcm5hbCBwbGVhc3U=", "any carnal pleasu"); + decode("YW55IGNhcm5hbCBwbGVhc3Vy", "any carnal pleasur"); + } + + @Test + public void decodeUnpadded() { + decode("YW55IGNhcm5hbCBwbGVhcw", "any carnal pleas"); + decode("YW55IGNhcm5hbCBwbGVhc3U", "any carnal pleasu"); + decode("YW55IGNhcm5hbCBwbGVhc3Vy", "any carnal pleasur"); + } + + private static void decode(String base64, String expected) { + assertEquals(expected, new String(Base64.decode(base64), UTF8)); + } +} \ No newline at end of file