5
5
6
6
7
7
import static java .lang .String .format ;
8
+ import java .util .InputMismatchException ;
8
9
import java .nio .BufferOverflowException ;
9
10
import java .nio .BufferUnderflowException ;
10
- import javax .xml .bind .TypeConstraintException ;
11
- import javax .xml .bind .DataBindingException ;
12
11
13
12
14
13
/**
@@ -37,99 +36,104 @@ public class Image implements java.io.Serializable {
37
36
/**
38
37
* Serializes the object.
39
38
* @param buf the data destination.
40
- * @param offset the first byte index.
41
- * @return the index of the first byte after the last byte written .
39
+ * @param offset the initial index for {@code buf}, inclusive .
40
+ * @return the final index for {@code buf}, exclusive .
42
41
* @throws BufferOverflowException when {@code buf} is too small.
43
42
* @throws IllegalStateException on an upper limit breach defined by either {@link #colferSizeMax} or {@link #colferListMax}.
44
43
*/
45
44
public int marshal (byte [] buf , int offset ) {
46
45
int i = offset ;
47
46
try {
48
-
49
47
if (! this .uri .isEmpty ()) {
50
48
buf [i ++] = (byte ) 0 ;
51
- String s = this .uri ;
52
- int sLength = s .length ();
53
-
54
49
int start = ++i ;
55
- for (int sIndex = 0 ; sIndex < sLength ; sIndex ++) {
50
+
51
+ String s = this .uri ;
52
+ for (int sIndex = 0 , sLength = s .length (); sIndex < sLength ; sIndex ++) {
56
53
char c = s .charAt (sIndex );
57
- if (c < 128 ) {
54
+ if (c < '\u0080' ) {
58
55
buf [i ++] = (byte ) c ;
59
- } else if (c < 2048 ) {
56
+ } else if (c < '\u0800' ) {
60
57
buf [i ++] = (byte ) (192 | c >>> 6 );
61
58
buf [i ++] = (byte ) (128 | c & 63 );
62
- } else if (! Character . isSurrogate ( c ) ) {
59
+ } else if (c < '\ud800' || c > '\udfff' ) {
63
60
buf [i ++] = (byte ) (224 | c >>> 12 );
64
61
buf [i ++] = (byte ) (128 | c >>> 6 & 63 );
65
62
buf [i ++] = (byte ) (128 | c & 63 );
66
- } else if (++sIndex != sLength ) {
67
- int cp = Character .toCodePoint (c , s .charAt (sIndex ));
68
- buf [i ++] = (byte ) (240 | cp >>> 18 );
69
- buf [i ++] = (byte ) (128 | cp >>> 12 & 63 );
70
- buf [i ++] = (byte ) (128 | cp >>> 6 & 63 );
71
- buf [i ++] = (byte ) (128 | cp & 63 );
63
+ } else {
64
+ int cp = 0 ;
65
+ if (++sIndex < sLength ) cp = Character .toCodePoint (c , s .charAt (sIndex ));
66
+ if ((cp >= 1 << 16 ) && (cp < 1 << 21 )) {
67
+ buf [i ++] = (byte ) (240 | cp >>> 18 );
68
+ buf [i ++] = (byte ) (128 | cp >>> 12 & 63 );
69
+ buf [i ++] = (byte ) (128 | cp >>> 6 & 63 );
70
+ buf [i ++] = (byte ) (128 | cp & 63 );
71
+ } else
72
+ buf [i ++] = (byte ) '?' ;
72
73
}
73
74
}
74
-
75
75
int size = i - start ;
76
76
if (size > colferSizeMax )
77
77
throw new IllegalStateException (format ("colfer: field serializers/colfer/media.image.uri size %d exceeds %d UTF-8 bytes" , size , colferSizeMax ));
78
78
79
- int shift = 0 ;
80
- for (int x = size ; (x & ~((1 << 7 ) - 1 )) != 0 ; x >>>= 7 ) shift ++;
81
- if (shift != 0 ) System .arraycopy (buf , start , buf , start + shift , size );
82
- i = start + shift + size ;
79
+ int ii = start - 1 ;
80
+ if (size > 0x7f ) {
81
+ i ++;
82
+ for (int x = size ; x >= 1 << 14 ; x >>>= 7 ) i ++;
83
+ System .arraycopy (buf , start , buf , i - size , size );
83
84
84
- start --;
85
- while (( size & ~(( 1 << 7 ) - 1 )) != 0 ) {
86
- buf [ start ++] = ( byte ) ( size | 0x80 ) ;
87
- size >>>= 7 ;
85
+ do {
86
+ buf [ ii ++] = ( byte ) ( size | 0x80 );
87
+ size >>>= 7 ;
88
+ } while ( size > 0x7f ) ;
88
89
}
89
- buf [start ++ ] = (byte ) size ;
90
+ buf [ii ] = (byte ) size ;
90
91
}
91
92
92
93
if (! this .title .isEmpty ()) {
93
94
buf [i ++] = (byte ) 1 ;
94
- String s = this .title ;
95
- int sLength = s .length ();
96
-
97
95
int start = ++i ;
98
- for (int sIndex = 0 ; sIndex < sLength ; sIndex ++) {
96
+
97
+ String s = this .title ;
98
+ for (int sIndex = 0 , sLength = s .length (); sIndex < sLength ; sIndex ++) {
99
99
char c = s .charAt (sIndex );
100
- if (c < 128 ) {
100
+ if (c < '\u0080' ) {
101
101
buf [i ++] = (byte ) c ;
102
- } else if (c < 2048 ) {
102
+ } else if (c < '\u0800' ) {
103
103
buf [i ++] = (byte ) (192 | c >>> 6 );
104
104
buf [i ++] = (byte ) (128 | c & 63 );
105
- } else if (! Character . isSurrogate ( c ) ) {
105
+ } else if (c < '\ud800' || c > '\udfff' ) {
106
106
buf [i ++] = (byte ) (224 | c >>> 12 );
107
107
buf [i ++] = (byte ) (128 | c >>> 6 & 63 );
108
108
buf [i ++] = (byte ) (128 | c & 63 );
109
- } else if (++sIndex != sLength ) {
110
- int cp = Character .toCodePoint (c , s .charAt (sIndex ));
111
- buf [i ++] = (byte ) (240 | cp >>> 18 );
112
- buf [i ++] = (byte ) (128 | cp >>> 12 & 63 );
113
- buf [i ++] = (byte ) (128 | cp >>> 6 & 63 );
114
- buf [i ++] = (byte ) (128 | cp & 63 );
109
+ } else {
110
+ int cp = 0 ;
111
+ if (++sIndex < sLength ) cp = Character .toCodePoint (c , s .charAt (sIndex ));
112
+ if ((cp >= 1 << 16 ) && (cp < 1 << 21 )) {
113
+ buf [i ++] = (byte ) (240 | cp >>> 18 );
114
+ buf [i ++] = (byte ) (128 | cp >>> 12 & 63 );
115
+ buf [i ++] = (byte ) (128 | cp >>> 6 & 63 );
116
+ buf [i ++] = (byte ) (128 | cp & 63 );
117
+ } else
118
+ buf [i ++] = (byte ) '?' ;
115
119
}
116
120
}
117
-
118
121
int size = i - start ;
119
122
if (size > colferSizeMax )
120
123
throw new IllegalStateException (format ("colfer: field serializers/colfer/media.image.title size %d exceeds %d UTF-8 bytes" , size , colferSizeMax ));
121
124
122
- int shift = 0 ;
123
- for (int x = size ; (x & ~((1 << 7 ) - 1 )) != 0 ; x >>>= 7 ) shift ++;
124
- if (shift != 0 ) System .arraycopy (buf , start , buf , start + shift , size );
125
- i = start + shift + size ;
125
+ int ii = start - 1 ;
126
+ if (size > 0x7f ) {
127
+ i ++;
128
+ for (int x = size ; x >= 1 << 14 ; x >>>= 7 ) i ++;
129
+ System .arraycopy (buf , start , buf , i - size , size );
126
130
127
- start --;
128
- while (( size & ~(( 1 << 7 ) - 1 )) != 0 ) {
129
- buf [ start ++] = ( byte ) ( size | 0x80 ) ;
130
- size >>>= 7 ;
131
+ do {
132
+ buf [ ii ++] = ( byte ) ( size | 0x80 );
133
+ size >>>= 7 ;
134
+ } while ( size > 0x7f ) ;
131
135
}
132
- buf [start ++ ] = (byte ) size ;
136
+ buf [ii ] = (byte ) size ;
133
137
}
134
138
135
139
if (this .width != 0 ) {
@@ -139,7 +143,7 @@ public int marshal(byte[] buf, int offset) {
139
143
buf [i ++] = (byte ) (2 | 0x80 );
140
144
} else
141
145
buf [i ++] = (byte ) 2 ;
142
- while ((x & ~(( 1 << 7 ) - 1 ) ) != 0 ) {
146
+ while ((x & ~0x7f ) != 0 ) {
143
147
buf [i ++] = (byte ) (x | 0x80 );
144
148
x >>>= 7 ;
145
149
}
@@ -153,7 +157,7 @@ public int marshal(byte[] buf, int offset) {
153
157
buf [i ++] = (byte ) (3 | 0x80 );
154
158
} else
155
159
buf [i ++] = (byte ) 3 ;
156
- while ((x & ~(( 1 << 7 ) - 1 ) ) != 0 ) {
160
+ while ((x & ~0x7f ) != 0 ) {
157
161
buf [i ++] = (byte ) (x | 0x80 );
158
162
x >>>= 7 ;
159
163
}
@@ -175,50 +179,53 @@ public int marshal(byte[] buf, int offset) {
175
179
throw new IllegalStateException (format ("colfer: serial exceeds %d bytes" , colferSizeMax ));
176
180
if (i >= buf .length )
177
181
throw new BufferOverflowException ();
178
- throw new RuntimeException ( "colfer: bug" , e ) ;
182
+ throw e ;
179
183
}
180
184
}
181
185
182
186
/**
183
187
* Deserializes the object.
184
188
* @param buf the data source.
185
- * @param offset the first byte index.
186
- * @return the index of the first byte after the last byte read .
189
+ * @param offset the initial index for {@code buf}, inclusive .
190
+ * @return the final index for {@code buf}, exclusive .
187
191
* @throws BufferUnderflowException when {@code buf} is incomplete. (EOF)
188
- * @throws TypeConstraintException on an upper limit breach defined by either {@link #colferSizeMax} or {@link #colferListMax}.
189
- * @throws DataBindingException when the data does not match this object's schema.
192
+ * @throws SecurityException on an upper limit breach defined by either {@link #colferSizeMax} or {@link #colferListMax}.
193
+ * @throws InputMismatchException when the data does not match this object's schema.
190
194
*/
191
- public int unmarshal (byte [] buf , int offset )
192
- throws BufferUnderflowException , TypeConstraintException , DataBindingException {
195
+ public int unmarshal (byte [] buf , int offset ) {
193
196
int i = offset ;
194
197
try {
195
198
byte header = buf [i ++];
196
199
197
200
if (header == (byte ) 0 ) {
198
- int n = 0 ;
201
+ int size = 0 ;
199
202
for (int shift = 0 ; true ; shift += 7 ) {
200
203
byte b = buf [i ++];
201
- n |= (b & 0x7f ) << shift ;
204
+ size |= (b & 0x7f ) << shift ;
202
205
if (shift == 28 || b >= 0 ) break ;
203
206
}
204
- if (n > colferSizeMax )
205
- throw new TypeConstraintException (format ("colfer: field serializers/colfer/media.image.uri size %d exceeds %d UTF-8 bytes" , n , colferSizeMax ));
206
- this .uri = new String (buf , i , n , this ._utf8 );
207
- i += n ;
207
+ if (size > colferSizeMax )
208
+ throw new SecurityException (format ("colfer: field serializers/colfer/media.image.uri size %d exceeds %d UTF-8 bytes" , size , colferSizeMax ));
209
+
210
+ int start = i ;
211
+ i += size ;
212
+ this .uri = new String (buf , start , size , this ._utf8 );
208
213
header = buf [i ++];
209
214
}
210
215
211
216
if (header == (byte ) 1 ) {
212
- int n = 0 ;
217
+ int size = 0 ;
213
218
for (int shift = 0 ; true ; shift += 7 ) {
214
219
byte b = buf [i ++];
215
- n |= (b & 0x7f ) << shift ;
220
+ size |= (b & 0x7f ) << shift ;
216
221
if (shift == 28 || b >= 0 ) break ;
217
222
}
218
- if (n > colferSizeMax )
219
- throw new TypeConstraintException (format ("colfer: field serializers/colfer/media.image.title size %d exceeds %d UTF-8 bytes" , n , colferSizeMax ));
220
- this .title = new String (buf , i , n , this ._utf8 );
221
- i += n ;
223
+ if (size > colferSizeMax )
224
+ throw new SecurityException (format ("colfer: field serializers/colfer/media.image.title size %d exceeds %d UTF-8 bytes" , size , colferSizeMax ));
225
+
226
+ int start = i ;
227
+ i += size ;
228
+ this .title = new String (buf , start , size , this ._utf8 );
222
229
header = buf [i ++];
223
230
}
224
231
@@ -273,15 +280,17 @@ public int unmarshal(byte[] buf, int offset)
273
280
}
274
281
275
282
if (header != (byte ) 0x7f )
276
- throw new DataBindingException (format ("colfer: unknown header at byte %d" , i - 1 ), null );
283
+ throw new InputMismatchException (format ("colfer: unknown header at byte %d" , i - 1 ));
277
284
} catch (IndexOutOfBoundsException e ) {
278
285
if (i - offset > colferSizeMax )
279
- throw new TypeConstraintException (format ("colfer: serial exceeds %d bytes" , colferSizeMax ));
286
+ throw new SecurityException (format ("colfer: serial exceeds %d bytes" , colferSizeMax ));
280
287
if (i >= buf .length )
281
288
throw new BufferUnderflowException ();
282
289
throw new RuntimeException ("colfer: bug" , e );
283
290
}
284
291
292
+ if (i - offset > colferSizeMax )
293
+ throw new SecurityException (format ("colfer: serial exceeds %d bytes" , colferSizeMax ));
285
294
return i ;
286
295
}
287
296
@@ -335,7 +344,14 @@ public void setLarge(boolean value) {
335
344
336
345
@ Override
337
346
public final int hashCode () {
338
- return java .util .Objects .hash (0x7f , uri , title , width , height , small , large );
347
+ int h = 1 ;
348
+ if (this .uri != null ) h = 31 * h + this .uri .hashCode ();
349
+ if (this .title != null ) h = 31 * h + this .title .hashCode ();
350
+ h = 31 * h + this .width ;
351
+ h = 31 * h + this .height ;
352
+ h = 31 * h + (this .small ? 1231 : 1237 );
353
+ h = 31 * h + (this .large ? 1231 : 1237 );
354
+ return h ;
339
355
}
340
356
341
357
@ Override
0 commit comments