THRIFT-3276 Binary data does not decode correctly using the TJSONProtocol when the base64 encoded data is padded.
This closes #645
diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
index e4077bc..6865fdc 100644
--- a/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
+++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.cpp
@@ -761,6 +761,11 @@
throw TProtocolException(TProtocolException::SIZE_LIMIT);
uint32_t len = static_cast<uint32_t>(tmp.length());
str.clear();
+ // Ignore padding
+ uint32_t bound = len >= 2 ? len - 2 : 0;
+ for (uint32_t i = len - 1; i >= bound && b[i] == '='; --i) {
+ --len;
+ }
while (len >= 4) {
base64_decode(b, 4);
str.append((const char*)b, 3);
diff --git a/lib/cpp/src/thrift/protocol/TJSONProtocol.h b/lib/cpp/src/thrift/protocol/TJSONProtocol.h
index 3c7b9d7..80d68a4 100644
--- a/lib/cpp/src/thrift/protocol/TJSONProtocol.h
+++ b/lib/cpp/src/thrift/protocol/TJSONProtocol.h
@@ -53,6 +53,10 @@
* The readBinary() method is written such that it will properly skip if
* called on a Thrift string (although it will decode garbage data).
*
+ * NOTE: Base64 padding is optional for Thrift binary value encoding. So
+ * the readBinary() method needs to decode both input strings with padding
+ * and those without one.
+ *
* 5. Thrift structs are represented as JSON objects, with the field ID as the
* key, and the field value represented as a JSON object with a single
* key-value pair. The key is a short string identifier for that type,
diff --git a/lib/csharp/src/Protocol/TJSONProtocol.cs b/lib/csharp/src/Protocol/TJSONProtocol.cs
index 2e8d99f..4081d6e 100644
--- a/lib/csharp/src/Protocol/TJSONProtocol.cs
+++ b/lib/csharp/src/Protocol/TJSONProtocol.cs
@@ -544,6 +544,11 @@
int len = b.Length;
int off = 0;
+ // Ignore padding
+ int bound = len >= 2 ? len - 2 : 0;
+ for (int i = len - 1; i >= bound && b[i] == '='; --i) {
+ --len;
+ }
while (len >= 3)
{
// Encode 3 bytes at a time
diff --git a/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java b/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
index f51322c..9876e13 100644
--- a/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
@@ -769,6 +769,11 @@
int len = arr.len();
int off = 0;
int size = 0;
+ // Ignore padding
+ int bound = len >= 2 ? len - 2 : 0;
+ for (int i = len - 1; i >= bound && b[i] == '='; --i) {
+ --len;
+ }
while (len >= 4) {
// Decode 4 bytes at a time
TBase64Utils.decode(b, off, 4, b, size); // NB: decoded in place
diff --git a/lib/javame/src/org/apache/thrift/protocol/TJSONProtocol.java b/lib/javame/src/org/apache/thrift/protocol/TJSONProtocol.java
index de7086f..99e3d2a 100644
--- a/lib/javame/src/org/apache/thrift/protocol/TJSONProtocol.java
+++ b/lib/javame/src/org/apache/thrift/protocol/TJSONProtocol.java
@@ -722,6 +722,11 @@
int len = arr.len();
int off = 0;
int size = 0;
+ // Ignore padding
+ int bound = len >= 2 ? len - 2 : 0;
+ for (int i = len - 1; i >= bound && b[i] == '='; --i) {
+ --len;
+ }
while (len >= 4) {
// Decode 4 bytes at a time
TBase64Utils.decode(b, off, 4, b, size); // NB: decoded in place