xref: /aosp_15_r20/external/jackson-core/src/test/java/com/fasterxml/jackson/core/json/TestRootValues.java (revision 944f89f84d71c7cfddf0d16e984cab583aa14be3)
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