1 package com.fasterxml.jackson.core.json; 2 3 import java.io.*; 4 5 import com.fasterxml.jackson.core.*; 6 7 public class TestRootValues 8 extends com.fasterxml.jackson.core.BaseTest 9 { 10 static class Issue516InputStream extends InputStream 11 { 12 private final byte[][] reads; 13 private int currentRead; 14 Issue516InputStream(byte[][] reads)15 public Issue516InputStream(byte[][] reads) { 16 this.reads = reads; 17 this.currentRead = 0; 18 } 19 20 @Override read()21 public int read() throws IOException { 22 throw new UnsupportedOperationException(); 23 } 24 25 @Override read(byte[] b, int off, int len)26 public int read(byte[] b, int off, int len) throws IOException { 27 if (currentRead >= reads.length) { 28 return -1; 29 } 30 byte[] bytes = reads[currentRead++]; 31 if (len < bytes.length) { 32 throw new IllegalArgumentException(); 33 } 34 System.arraycopy(bytes, 0, b, off, bytes.length); 35 return bytes.length; 36 } 37 } 38 39 static class Issue516Reader extends Reader 40 { 41 private final char[][] reads; 42 private int currentRead; 43 Issue516Reader(char[][] reads)44 public Issue516Reader(char[][] reads) { 45 this.reads = reads; 46 this.currentRead = 0; 47 } 48 49 @Override close()50 public void close() { } 51 52 @Override read()53 public int read() throws IOException { 54 throw new UnsupportedOperationException(); 55 } 56 57 @Override read(char[] b, int off, int len)58 public int read(char[] b, int off, int len) throws IOException { 59 if (currentRead >= reads.length) { 60 return -1; 61 } 62 char[] bytes = reads[currentRead++]; 63 if (len < bytes.length) { 64 throw new IllegalArgumentException(); 65 } 66 System.arraycopy(bytes, 0, b, off, bytes.length); 67 return bytes.length; 68 } 69 } 70 71 /* 72 /********************************************************** 73 /* Test methods, reads 74 /********************************************************** 75 */ 76 77 private final JsonFactory JSON_F = sharedStreamFactory(); 78 testSimpleNumbers()79 public void testSimpleNumbers() throws Exception { 80 // DataInput can not detect EOF so: 81 _testSimpleNumbers(MODE_INPUT_STREAM); 82 _testSimpleNumbers(MODE_INPUT_STREAM_THROTTLED); 83 _testSimpleNumbers(MODE_READER); 84 } 85 _testSimpleNumbers(int mode)86 private void _testSimpleNumbers(int mode) throws Exception 87 { 88 final String DOC = "1 2\t3\r4\n5\r\n6\r\n 7"; 89 JsonParser p = createParser(mode, DOC); 90 for (int i = 1; i <= 7; ++i) { 91 assertToken(JsonToken.VALUE_NUMBER_INT, p.nextToken()); 92 assertEquals(i, p.getIntValue()); 93 } 94 assertNull(p.nextToken()); 95 p.close(); 96 } 97 testBrokenNumber()98 public void testBrokenNumber() throws Exception 99 { 100 _testBrokenNumber(MODE_INPUT_STREAM); 101 _testBrokenNumber(MODE_INPUT_STREAM_THROTTLED); 102 _testBrokenNumber(MODE_READER); 103 // I think DataInput _SHOULD_ be able to detect, fail, but for now... 104 // _testBrokenNumber(MODE_DATA_INPUT); 105 } 106 _testBrokenNumber(int mode)107 private void _testBrokenNumber(int mode) throws Exception 108 { 109 final String DOC = "14:89:FD:D3:E7:8C"; 110 JsonParser p = createParser(mode, DOC); 111 // Should fail, right away 112 try { 113 p.nextToken(); 114 fail("Ought to fail! Instead, got token: "+p.currentToken()); 115 } catch (JsonParseException e) { 116 verifyException(e, "unexpected character"); 117 } 118 p.close(); 119 } 120 testSimpleBooleans()121 public void testSimpleBooleans() throws Exception { 122 // can't do DataInput so 123 _testSimpleBooleans(MODE_INPUT_STREAM); 124 _testSimpleBooleans(MODE_INPUT_STREAM_THROTTLED); 125 _testSimpleBooleans(MODE_READER); 126 } 127 _testSimpleBooleans(int mode)128 private void _testSimpleBooleans(int mode) throws Exception 129 { 130 final String DOC = "true false\ttrue\rfalse\ntrue\r\nfalse\r\n true"; 131 JsonParser p = createParser(mode, DOC); 132 boolean exp = true; 133 for (int i = 1; i <= 7; ++i) { 134 assertToken(exp ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE, p.nextToken()); 135 exp = !exp; 136 } 137 assertNull(p.nextToken()); 138 p.close(); 139 } 140 testInvalidToken()141 public void testInvalidToken() throws Exception 142 { 143 _testInvalidToken(MODE_INPUT_STREAM, '\u00c4'); 144 _testInvalidToken(MODE_INPUT_STREAM_THROTTLED, '\u00c4'); 145 _testInvalidToken(MODE_READER, '\u00c4'); 146 _testInvalidToken(MODE_DATA_INPUT, '\u00c4'); 147 148 _testInvalidToken(MODE_INPUT_STREAM, '\u3456'); 149 _testInvalidToken(MODE_INPUT_STREAM_THROTTLED, '\u3456'); 150 _testInvalidToken(MODE_READER, '\u3456'); 151 _testInvalidToken(MODE_DATA_INPUT, '\u3456'); 152 } 153 _testInvalidToken(int mode, char weirdChar)154 private void _testInvalidToken(int mode, char weirdChar) throws Exception 155 { 156 final String DOC = " A\u3456C "; 157 JsonParser p = createParser(mode, DOC); 158 // Should fail, right away 159 try { 160 p.nextToken(); 161 fail("Ought to fail! Instead, got token: "+p.currentToken()); 162 } catch (JsonParseException e) { 163 verifyException(e, "Unrecognized token"); 164 } 165 p.close(); 166 } 167 168 /* 169 /********************************************************** 170 /* Test methods, writes 171 /********************************************************** 172 */ 173 testSimpleWrites()174 public void testSimpleWrites() throws Exception 175 { 176 _testSimpleWrites(false); 177 _testSimpleWrites(true); 178 } 179 _testSimpleWrites(boolean useStream)180 private void _testSimpleWrites(boolean useStream) throws Exception 181 { 182 ByteArrayOutputStream out = new ByteArrayOutputStream(); 183 StringWriter w = new StringWriter(); 184 JsonGenerator gen; 185 186 if (useStream) { 187 gen = JSON_F.createGenerator(out, JsonEncoding.UTF8); 188 } else { 189 gen = JSON_F.createGenerator(w); 190 } 191 gen.writeNumber(123); 192 gen.writeString("abc"); 193 gen.writeBoolean(true); 194 195 gen.close(); 196 out.close(); 197 w.close(); 198 199 // and verify 200 String json = useStream ? out.toString("UTF-8") : w.toString(); 201 assertEquals("123 \"abc\" true", json); 202 } 203 204 /* 205 /********************************************************** 206 /* Test methods, other 207 /********************************************************** 208 */ 209 210 // [core#516]: Off-by-one read problem testRootOffsetIssue516Bytes()211 public void testRootOffsetIssue516Bytes() throws Exception 212 { 213 // InputStream that forces _parseNumber2 to be invoked. 214 final InputStream in = new Issue516InputStream(new byte[][] { 215 "1234".getBytes("UTF-8"), 216 "5 true".getBytes("UTF-8") 217 }); 218 219 JsonParser parser = JSON_F.createParser(in); 220 assertEquals(12345, parser.nextIntValue(0)); 221 222 // Fails with com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'rue': was expecting ('true', 'false' or 'null') 223 assertTrue(parser.nextBooleanValue()); 224 225 parser.close(); 226 in.close(); 227 } 228 229 // [core#516]: Off-by-one read problem testRootOffsetIssue516Chars()230 public void testRootOffsetIssue516Chars() throws Exception 231 { 232 // InputStream that forces _parseNumber2 to be invoked. 233 final Reader in = new Issue516Reader(new char[][] { 234 "1234".toCharArray(), "5 true".toCharArray() 235 }); 236 237 JsonParser parser = JSON_F.createParser(in); 238 assertEquals(12345, parser.nextIntValue(0)); 239 240 // Fails with com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'rue': was expecting ('true', 'false' or 'null') 241 assertTrue(parser.nextBooleanValue()); 242 243 parser.close(); 244 in.close(); 245 } 246 } 247