Fix [JACKSON-709] for 1.9.x as well
diff --git a/release-notes/CREDITS b/release-notes/CREDITS
index 11b4d89..6eba2ec 100644
--- a/release-notes/CREDITS
+++ b/release-notes/CREDITS
@@ -733,6 +733,26 @@
"Internal Error"
[1.8.4]
+Paul Marynchev:
+ * Reported [JACKSON-637] NumberSerializer was missing proper handling of
+ Integer, Long
+ [1.8.5]
+
+Ransom Briggs:
+ * Reported [JACKSON-668] Problems with 'JsonParser.getDecimalValue'
+ not clearing earlier state
+ [1.8.6]
+
+William Burns:
+ * Reported [JACKSON-677], suggested fix for: Inner generic type references
+ not working properly
+ [1.8.6]
+
+Tom Boettcher:
+ * Reported [JACKSON-709] Problems converting base64-encoded Strings
+ between JsonNode, POJOs
+ [1.8.7]
+
Anand Hatrwalne:
* Requested [JACKSON-558] Add 'DeserializationConfig.Feature.UNWRAP_ROOT_VALUE' as
matching counterpart for 'SerializationConfig.Feature.WRAP_ROOT_VALUE'
diff --git a/src/java/org/codehaus/jackson/impl/JsonParserBase.java b/src/java/org/codehaus/jackson/impl/JsonParserBase.java
index 93665d4..686a6d8 100644
--- a/src/java/org/codehaus/jackson/impl/JsonParserBase.java
+++ b/src/java/org/codehaus/jackson/impl/JsonParserBase.java
@@ -432,8 +432,6 @@
protected abstract void _finishString() throws IOException, JsonParseException;
protected abstract void _closeInput() throws IOException;
-
- protected abstract byte[] _decodeBase64(Base64Variant b64variant) throws IOException, JsonParseException;
/*
/**********************************************************
diff --git a/src/java/org/codehaus/jackson/impl/JsonParserMinimalBase.java b/src/java/org/codehaus/jackson/impl/JsonParserMinimalBase.java
index 8d09c1d..1e5f6d0 100644
--- a/src/java/org/codehaus/jackson/impl/JsonParserMinimalBase.java
+++ b/src/java/org/codehaus/jackson/impl/JsonParserMinimalBase.java
@@ -5,11 +5,16 @@
import org.codehaus.jackson.*;
import org.codehaus.jackson.JsonParser.Feature;
import org.codehaus.jackson.io.NumberInput;
+import org.codehaus.jackson.util.ByteArrayBuilder;
/**
* Intermediate base class used by all Jackson {@link JsonParser}
* implementations, but does not add any additional fields that depend
* on particular method of obtaining input.
+ *<p>
+ * Note that 'minimal' here mostly refers to minimal number of fields
+ * (size) and functionality that is specific to certain types
+ * of parser implementations; but not necessarily to number of methods.
*
* @since 1.6
*
@@ -292,10 +297,141 @@
/*
/**********************************************************
- /* Error reporting
+ /* Base64 decoding
/**********************************************************
*/
+ /**
+ * Helper method that can be used for base64 decoding in cases where
+ * encoded content has already been read as a String.
+ *
+ * @since 1.9.3
+ */
+ protected void _decodeBase64(String str, ByteArrayBuilder builder, Base64Variant b64variant)
+ throws IOException, JsonParseException
+ {
+ int ptr = 0;
+ int len = str.length();
+
+ main_loop:
+ while (ptr < len) {
+ // first, we'll skip preceding white space, if any
+ char ch;
+ do {
+ ch = str.charAt(ptr++);
+ if (ptr >= len) {
+ break main_loop;
+ }
+ } while (ch <= INT_SPACE);
+ int bits = b64variant.decodeBase64Char(ch);
+ if (bits < 0) {
+ _reportInvalidBase64(b64variant, ch, 0, null);
+ }
+ int decodedData = bits;
+ // then second base64 char; can't get padding yet, nor ws
+ if (ptr >= len) {
+ _reportBase64EOF();
+ }
+ ch = str.charAt(ptr++);
+ bits = b64variant.decodeBase64Char(ch);
+ if (bits < 0) {
+ _reportInvalidBase64(b64variant, ch, 1, null);
+ }
+ decodedData = (decodedData << 6) | bits;
+ // third base64 char; can be padding, but not ws
+ if (ptr >= len) {
+ // but as per [JACKSON-631] can be end-of-input, iff not using padding
+ if (!b64variant.usesPadding()) {
+ decodedData >>= 4;
+ builder.append(decodedData);
+ break;
+ }
+ _reportBase64EOF();
+ }
+ ch = str.charAt(ptr++);
+ bits = b64variant.decodeBase64Char(ch);
+
+ // First branch: can get padding (-> 1 byte)
+ if (bits < 0) {
+ if (bits != Base64Variant.BASE64_VALUE_PADDING) {
+ _reportInvalidBase64(b64variant, ch, 2, null);
+ }
+ // Ok, must get padding
+ if (ptr >= len) {
+ _reportBase64EOF();
+ }
+ ch = str.charAt(ptr++);
+ if (!b64variant.usesPaddingChar(ch)) {
+ _reportInvalidBase64(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'");
+ }
+ // Got 12 bits, only need 8, need to shift
+ decodedData >>= 4;
+ builder.append(decodedData);
+ continue;
+ }
+ // Nope, 2 or 3 bytes
+ decodedData = (decodedData << 6) | bits;
+ // fourth and last base64 char; can be padding, but not ws
+ if (ptr >= len) {
+ // but as per [JACKSON-631] can be end-of-input, iff not using padding
+ if (!b64variant.usesPadding()) {
+ decodedData >>= 2;
+ builder.appendTwoBytes(decodedData);
+ break;
+ }
+ _reportBase64EOF();
+ }
+ ch = str.charAt(ptr++);
+ bits = b64variant.decodeBase64Char(ch);
+ if (bits < 0) {
+ if (bits != Base64Variant.BASE64_VALUE_PADDING) {
+ _reportInvalidBase64(b64variant, ch, 3, null);
+ }
+ decodedData >>= 2;
+ builder.appendTwoBytes(decodedData);
+ } else {
+ // otherwise, our triple is now complete
+ decodedData = (decodedData << 6) | bits;
+ builder.appendThreeBytes(decodedData);
+ }
+ }
+ }
+
+ /**
+ * @param bindex Relative index within base64 character unit; between 0
+ * and 3 (as unit has exactly 4 characters)
+ */
+ protected void _reportInvalidBase64(Base64Variant b64variant, char ch, int bindex, String msg)
+ throws JsonParseException
+ {
+ String base;
+ if (ch <= INT_SPACE) {
+ base = "Illegal white space character (code 0x"+Integer.toHexString(ch)+") as character #"+(bindex+1)+" of 4-char base64 unit: can only used between units";
+ } else if (b64variant.usesPaddingChar(ch)) {
+ base = "Unexpected padding character ('"+b64variant.getPaddingChar()+"') as character #"+(bindex+1)+" of 4-char base64 unit: padding only legal as 3rd or 4th character";
+ } else if (!Character.isDefined(ch) || Character.isISOControl(ch)) {
+ // Not sure if we can really get here... ? (most illegal xml chars are caught at lower level)
+ base = "Illegal character (code 0x"+Integer.toHexString(ch)+") in base64 content";
+ } else {
+ base = "Illegal character '"+ch+"' (code 0x"+Integer.toHexString(ch)+") in base64 content";
+ }
+ if (msg != null) {
+ base = base + ": " + msg;
+ }
+ throw _constructError(base);
+ }
+
+ protected void _reportBase64EOF() throws JsonParseException {
+ throw _constructError("Unexpected end-of-String in base64 content");
+ }
+
+
+ /*
+ /**********************************************************
+ /* Error reporting
+ /**********************************************************
+ */
+
protected void _reportUnexpectedChar(int ch, String comment)
throws JsonParseException
{
diff --git a/src/java/org/codehaus/jackson/impl/ReaderBasedParser.java b/src/java/org/codehaus/jackson/impl/ReaderBasedParser.java
index 3e215df..a6b07ff 100644
--- a/src/java/org/codehaus/jackson/impl/ReaderBasedParser.java
+++ b/src/java/org/codehaus/jackson/impl/ReaderBasedParser.java
@@ -329,7 +329,13 @@
* textual content in error cases
*/
_tokenIncomplete = false;
- }
+ } else { // may actually require conversion...
+ if (_binaryValue == null) {
+ ByteArrayBuilder builder = _getByteArrayBuilder();
+ _decodeBase64(getText(), builder, b64variant);
+ _binaryValue = builder.toByteArray();
+ }
+ }
return _binaryValue;
}
@@ -1664,7 +1670,10 @@
/**********************************************************
*/
- @Override
+ /**
+ * Efficient handling for incremental parsing of base64-encoded
+ * textual content.
+ */
protected byte[] _decodeBase64(Base64Variant b64variant)
throws IOException, JsonParseException
{
@@ -1757,12 +1766,11 @@
bits = _decodeBase64Escape(b64variant, ch, 3);
}
if (bits == Base64Variant.BASE64_VALUE_PADDING) {
- /* With padding we only get 2 bytes; but we have
- * to shift it a bit so it is identical to triplet
- * case with partial output.
- * 3 chars gives 3x6 == 18 bits, of which 2 are
- * dummies, need to discard:
- */
+ // With padding we only get 2 bytes; but we have
+ // to shift it a bit so it is identical to triplet
+ // case with partial output.
+ // 3 chars gives 3x6 == 18 bits, of which 2 are
+ // dummies, need to discard:
decodedData >>= 2;
builder.appendTwoBytes(decodedData);
continue;
diff --git a/src/java/org/codehaus/jackson/impl/Utf8StreamParser.java b/src/java/org/codehaus/jackson/impl/Utf8StreamParser.java
index 5de0a8f..00527ed 100644
--- a/src/java/org/codehaus/jackson/impl/Utf8StreamParser.java
+++ b/src/java/org/codehaus/jackson/impl/Utf8StreamParser.java
@@ -405,7 +405,13 @@
* textual content in error cases
*/
_tokenIncomplete = false;
- }
+ } else { // may actually require conversion...
+ if (_binaryValue == null) {
+ ByteArrayBuilder builder = _getByteArrayBuilder();
+ _decodeBase64(getText(), builder, b64variant);
+ _binaryValue = builder.toByteArray();
+ }
+ }
return _binaryValue;
}
@@ -2827,7 +2833,10 @@
/**********************************************************
*/
- @Override
+ /**
+ * Efficient handling for incremental parsing of base64-encoded
+ * textual content.
+ */
protected byte[] _decodeBase64(Base64Variant b64variant)
throws IOException, JsonParseException
{
diff --git a/src/java/org/codehaus/jackson/util/TokenBuffer.java b/src/java/org/codehaus/jackson/util/TokenBuffer.java
index 60a3ee4..3c3cfb5 100644
--- a/src/java/org/codehaus/jackson/util/TokenBuffer.java
+++ b/src/java/org/codehaus/jackson/util/TokenBuffer.java
@@ -1090,96 +1090,6 @@
/**********************************************************
*/
- protected void _decodeBase64(String str, ByteArrayBuilder builder, Base64Variant b64variant)
- throws IOException, JsonParseException
- {
- int ptr = 0;
- int len = str.length();
-
- main_loop:
- while (ptr < len) {
- // first, we'll skip preceding white space, if any
- char ch;
- do {
- ch = str.charAt(ptr++);
- if (ptr >= len) {
- break main_loop;
- }
- } while (ch <= INT_SPACE);
- int bits = b64variant.decodeBase64Char(ch);
- if (bits < 0) {
- _reportInvalidBase64(b64variant, ch, 0, null);
- }
- int decodedData = bits;
- // then second base64 char; can't get padding yet, nor ws
- if (ptr >= len) {
- _reportBase64EOF();
- }
- ch = str.charAt(ptr++);
- bits = b64variant.decodeBase64Char(ch);
- if (bits < 0) {
- _reportInvalidBase64(b64variant, ch, 1, null);
- }
- decodedData = (decodedData << 6) | bits;
- // third base64 char; can be padding, but not ws
- if (ptr >= len) {
- // but as per [JACKSON-631] can be end-of-input, iff not using padding
- if (!b64variant.usesPadding()) {
- decodedData >>= 4;
- builder.append(decodedData);
- break;
- }
- _reportBase64EOF();
- }
- ch = str.charAt(ptr++);
- bits = b64variant.decodeBase64Char(ch);
-
- // First branch: can get padding (-> 1 byte)
- if (bits < 0) {
- if (bits != Base64Variant.BASE64_VALUE_PADDING) {
- _reportInvalidBase64(b64variant, ch, 2, null);
- }
- // Ok, must get padding
- if (ptr >= len) {
- _reportBase64EOF();
- }
- ch = str.charAt(ptr++);
- if (!b64variant.usesPaddingChar(ch)) {
- _reportInvalidBase64(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'");
- }
- // Got 12 bits, only need 8, need to shift
- decodedData >>= 4;
- builder.append(decodedData);
- continue;
- }
- // Nope, 2 or 3 bytes
- decodedData = (decodedData << 6) | bits;
- // fourth and last base64 char; can be padding, but not ws
- if (ptr >= len) {
- // but as per [JACKSON-631] can be end-of-input, iff not using padding
- if (!b64variant.usesPadding()) {
- decodedData >>= 2;
- builder.appendTwoBytes(decodedData);
- break;
- }
- _reportBase64EOF();
- }
- ch = str.charAt(ptr++);
- bits = b64variant.decodeBase64Char(ch);
- if (bits < 0) {
- if (bits != Base64Variant.BASE64_VALUE_PADDING) {
- _reportInvalidBase64(b64variant, ch, 3, null);
- }
- decodedData >>= 2;
- builder.appendTwoBytes(decodedData);
- } else {
- // otherwise, our triple is now complete
- decodedData = (decodedData << 6) | bits;
- builder.appendThreeBytes(decodedData);
- }
- }
- }
-
protected final Object _currentObject() {
return _segment.get(_segmentPtr);
}
@@ -1191,34 +1101,6 @@
}
}
- /**
- * @param bindex Relative index within base64 character unit; between 0
- * and 3 (as unit has exactly 4 characters)
- */
- protected void _reportInvalidBase64(Base64Variant b64variant, char ch, int bindex, String msg)
- throws JsonParseException
- {
- String base;
- if (ch <= INT_SPACE) {
- base = "Illegal white space character (code 0x"+Integer.toHexString(ch)+") as character #"+(bindex+1)+" of 4-char base64 unit: can only used between units";
- } else if (b64variant.usesPaddingChar(ch)) {
- base = "Unexpected padding character ('"+b64variant.getPaddingChar()+"') as character #"+(bindex+1)+" of 4-char base64 unit: padding only legal as 3rd or 4th character";
- } else if (!Character.isDefined(ch) || Character.isISOControl(ch)) {
- // Not sure if we can really get here... ? (most illegal xml chars are caught at lower level)
- base = "Illegal character (code 0x"+Integer.toHexString(ch)+") in base64 content";
- } else {
- base = "Illegal character '"+ch+"' (code 0x"+Integer.toHexString(ch)+") in base64 content";
- }
- if (msg != null) {
- base = base + ": " + msg;
- }
- throw _constructError(base);
- }
-
- protected void _reportBase64EOF() throws JsonParseException {
- throw _constructError("Unexpected end-of-String in base64 content");
- }
-
@Override
protected void _handleEOF() throws JsonParseException {
_throwInternal();
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java b/src/mapper/java/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java
index a3428a4..9945bec 100644
--- a/src/mapper/java/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java
+++ b/src/mapper/java/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java
@@ -283,7 +283,7 @@
throws IOException, JsonProcessingException
{
JsonToken t = jp.getCurrentToken();
-
+
// Most likely case: base64 encoded String?
if (t == JsonToken.VALUE_STRING) {
return jp.getBinaryValue(ctxt.getBase64Variant());
diff --git a/src/mapper/java/org/codehaus/jackson/node/TreeTraversingParser.java b/src/mapper/java/org/codehaus/jackson/node/TreeTraversingParser.java
index 147edab..42586df 100644
--- a/src/mapper/java/org/codehaus/jackson/node/TreeTraversingParser.java
+++ b/src/mapper/java/org/codehaus/jackson/node/TreeTraversingParser.java
@@ -306,11 +306,17 @@
}
@Override
- public Object getEmbeddedObject() {
+ public Object getEmbeddedObject()
+ {
if (!_closed) {
JsonNode n = currentNode();
- if (n != null && n.isPojo()) {
- return ((POJONode) n).getPojo();
+ if (n != null) {
+ if (n.isPojo()) {
+ return ((POJONode) n).getPojo();
+ }
+ if (n.isBinary()) {
+ return ((BinaryNode) n).getBinaryValue();
+ }
}
}
return null;
diff --git a/src/smile/java/org/codehaus/jackson/smile/SmileParser.java b/src/smile/java/org/codehaus/jackson/smile/SmileParser.java
index bbb55d2..3f636fa 100644
--- a/src/smile/java/org/codehaus/jackson/smile/SmileParser.java
+++ b/src/smile/java/org/codehaus/jackson/smile/SmileParser.java
@@ -1186,7 +1186,11 @@
return _binaryValue;
}
- @Override
+ /* NOTE: must still implement just because 1.9.0 - 1.9.2 did require
+ * its implementation (and we'll try to avoid introducing binary
+ * incompatibilities); however, should be deleted from 2.0
+ */
+ // @Deprecated
protected byte[] _decodeBase64(Base64Variant b64variant)
throws IOException, JsonParseException
{
diff --git a/src/test/org/codehaus/jackson/map/TestFormatSchema.java b/src/test/org/codehaus/jackson/map/TestFormatSchema.java
index 910cf78..d5f88b9 100644
--- a/src/test/org/codehaus/jackson/map/TestFormatSchema.java
+++ b/src/test/org/codehaus/jackson/map/TestFormatSchema.java
@@ -67,11 +67,6 @@
public void setSchema(FormatSchema schema) {
throw new SchemaException(schema);
}
-
- @Override
- protected byte[] _decodeBase64(Base64Variant b64variant) {
- return null;
- }
@Override
protected void _finishString() throws IOException, JsonParseException { }