1
1
/*
2
- * Copyright (c) 2014, 2017 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2014, 2021 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* This code is free software; you can redistribute it and/or modify it
@@ -59,41 +59,26 @@ ImageStrings getStrings() {
59
59
return strings ;
60
60
}
61
61
62
- static long [] decompress (ByteBuffer bytes ) {
62
+ static long [] decompress (ByteBuffer bytes , int offset ) {
63
63
Objects .requireNonNull (bytes );
64
64
long [] attributes = new long [ATTRIBUTE_COUNT ];
65
65
66
- if (bytes != null ) {
67
- while (bytes .hasRemaining ()) {
68
- int data = bytes .get () & 0xFF ;
69
- int kind = data >>> 3 ;
70
-
71
- if (kind == ATTRIBUTE_END ) {
72
- break ;
73
- }
74
-
75
- if (kind < ATTRIBUTE_END || ATTRIBUTE_COUNT <= kind ) {
76
- throw new InternalError (
77
- "Invalid jimage attribute kind: " + kind );
78
- }
79
-
80
- int length = (data & 0x7 ) + 1 ;
81
- long value = 0 ;
82
-
83
- for (int j = 0 ; j < length ; j ++) {
84
- value <<= 8 ;
85
-
86
- if (!bytes .hasRemaining ()) {
87
- throw new InternalError ("Missing jimage attribute data" );
88
- }
89
-
90
- value |= bytes .get () & 0xFF ;
91
- }
92
-
93
- attributes [kind ] = value ;
66
+ int limit = bytes .limit ();
67
+ while (offset < limit ) {
68
+ int data = bytes .get (offset ++) & 0xFF ;
69
+ if (data <= 0x7 ) { // ATTRIBUTE_END
70
+ break ;
71
+ }
72
+ int kind = data >>> 3 ;
73
+ if (ATTRIBUTE_COUNT <= kind ) {
74
+ throw new InternalError (
75
+ "Invalid jimage attribute kind: " + kind );
94
76
}
95
- }
96
77
78
+ int length = (data & 0x7 ) + 1 ;
79
+ attributes [kind ] = readValue (length , bytes , offset , limit );
80
+ offset += length ;
81
+ }
97
82
return attributes ;
98
83
}
99
84
@@ -126,71 +111,125 @@ public boolean verify(String name) {
126
111
/**
127
112
* A simpler verification would be {@code name.equals(getFullName())}, but
128
113
* by not creating the full name and enabling early returns we allocate
129
- * fewer objects. Could possibly be made allocation free by extending
130
- * ImageStrings to test if strings at an offset match the name region.
114
+ * fewer objects.
131
115
*/
132
116
static boolean verify (String name , long [] attributes , ImageStrings strings ) {
133
117
Objects .requireNonNull (name );
134
118
final int length = name .length ();
135
119
int index = 0 ;
136
120
int moduleOffset = (int )attributes [ATTRIBUTE_MODULE ];
137
- if (moduleOffset != 0 ) {
138
- String module = strings .get (moduleOffset );
139
- final int moduleLen = module .length ();
121
+ if (moduleOffset != 0 && length >= 1 ) {
122
+ int moduleLen = strings .match (moduleOffset , name , 1 );
140
123
index = moduleLen + 1 ;
141
- if (length <= index
124
+ if (moduleLen < 0
125
+ || length <= index
142
126
|| name .charAt (0 ) != '/'
143
- || !name .regionMatches (1 , module , 0 , moduleLen )
144
127
|| name .charAt (index ++) != '/' ) {
145
128
return false ;
146
129
}
147
130
}
131
+ return verifyName (null , name , index , length , 0 ,
132
+ (int ) attributes [ATTRIBUTE_PARENT ],
133
+ (int ) attributes [ATTRIBUTE_BASE ],
134
+ (int ) attributes [ATTRIBUTE_EXTENSION ],
135
+ strings );
136
+ }
148
137
149
- return verifyName (name , index , length , attributes , strings );
138
+ static boolean verify (String module , String name , ByteBuffer locations ,
139
+ int locationOffset , ImageStrings strings ) {
140
+ int moduleOffset = 0 ;
141
+ int parentOffset = 0 ;
142
+ int baseOffset = 0 ;
143
+ int extOffset = 0 ;
144
+
145
+ int limit = locations .limit ();
146
+ while (locationOffset < limit ) {
147
+ int data = locations .get (locationOffset ++) & 0xFF ;
148
+ if (data <= 0x7 ) { // ATTRIBUTE_END
149
+ break ;
150
+ }
151
+ int kind = data >>> 3 ;
152
+ if (ATTRIBUTE_COUNT <= kind ) {
153
+ throw new InternalError (
154
+ "Invalid jimage attribute kind: " + kind );
155
+ }
156
+
157
+ int length = (data & 0x7 ) + 1 ;
158
+ switch (kind ) {
159
+ case ATTRIBUTE_MODULE :
160
+ moduleOffset = (int ) readValue (length , locations , locationOffset , limit );
161
+ break ;
162
+ case ATTRIBUTE_BASE :
163
+ baseOffset = (int ) readValue (length , locations , locationOffset , limit );
164
+ break ;
165
+ case ATTRIBUTE_PARENT :
166
+ parentOffset = (int ) readValue (length , locations , locationOffset , limit );
167
+ break ;
168
+ case ATTRIBUTE_EXTENSION :
169
+ extOffset = (int ) readValue (length , locations , locationOffset , limit );
170
+ break ;
171
+ }
172
+ locationOffset += length ;
173
+ }
174
+ return verifyName (module , name , 0 , name .length (),
175
+ moduleOffset , parentOffset , baseOffset , extOffset , strings );
176
+ }
177
+
178
+ private static long readValue (int length , ByteBuffer buffer , int offset , int limit ) {
179
+ long value = 0 ;
180
+ for (int j = 0 ; j < length ; j ++) {
181
+ value <<= 8 ;
182
+ if (offset >= limit ) {
183
+ throw new InternalError ("Missing jimage attribute data" );
184
+ }
185
+ value |= buffer .get (offset ++) & 0xFF ;
186
+ }
187
+ return value ;
150
188
}
151
189
152
190
static boolean verify (String module , String name , long [] attributes ,
153
191
ImageStrings strings ) {
154
192
Objects .requireNonNull (module );
155
193
Objects .requireNonNull (name );
156
- int moduleOffset = (int )attributes [ATTRIBUTE_MODULE ];
194
+ return verifyName (module , name , 0 , name .length (),
195
+ (int ) attributes [ATTRIBUTE_MODULE ],
196
+ (int ) attributes [ATTRIBUTE_PARENT ],
197
+ (int ) attributes [ATTRIBUTE_BASE ],
198
+ (int ) attributes [ATTRIBUTE_EXTENSION ],
199
+ strings );
200
+ }
201
+
202
+ private static boolean verifyName (String module , String name , int index , int length ,
203
+ int moduleOffset , int parentOffset , int baseOffset , int extOffset , ImageStrings strings ) {
204
+
157
205
if (moduleOffset != 0 ) {
158
- if (! module . equals ( strings .get (moduleOffset ) )) {
206
+ if (strings .match (moduleOffset , module , 0 ) != module . length ( )) {
159
207
return false ;
160
208
}
161
209
}
162
-
163
- return verifyName (name , 0 , name .length (), attributes , strings );
164
- }
165
-
166
- private static boolean verifyName (String name , int index , int length ,
167
- long [] attributes , ImageStrings strings ) {
168
-
169
- int parentOffset = (int ) attributes [ATTRIBUTE_PARENT ];
170
210
if (parentOffset != 0 ) {
171
- String parent = strings .get (parentOffset );
172
- final int parentLen = parent .length ();
173
- if (!name .regionMatches (index , parent , 0 , parentLen )) {
211
+ int parentLen = strings .match (parentOffset , name , index );
212
+ if (parentLen < 0 ) {
174
213
return false ;
175
214
}
176
215
index += parentLen ;
177
216
if (length <= index || name .charAt (index ++) != '/' ) {
178
217
return false ;
179
218
}
180
219
}
181
- String base = strings .get ((int ) attributes [ATTRIBUTE_BASE ]);
182
- final int baseLen = base .length ();
183
- if (!name .regionMatches (index , base , 0 , baseLen )) {
220
+ int baseLen = strings .match (baseOffset , name , index );
221
+ if (baseLen < 0 ) {
184
222
return false ;
185
223
}
186
224
index += baseLen ;
187
- int extOffset = (int ) attributes [ATTRIBUTE_EXTENSION ];
188
225
if (extOffset != 0 ) {
189
- String extension = strings .get (extOffset );
190
- int extLen = extension .length ();
191
226
if (length <= index
192
- || name .charAt (index ++) != '.'
193
- || !name .regionMatches (index , extension , 0 , extLen )) {
227
+ || name .charAt (index ++) != '.' ) {
228
+ return false ;
229
+ }
230
+
231
+ int extLen = strings .match (extOffset , name , index );
232
+ if (extLen < 0 ) {
194
233
return false ;
195
234
}
196
235
index += extLen ;
@@ -203,7 +242,6 @@ long getAttribute(int kind) {
203
242
throw new InternalError (
204
243
"Invalid jimage attribute kind: " + kind );
205
244
}
206
-
207
245
return attributes [kind ];
208
246
}
209
247
@@ -212,7 +250,6 @@ String getAttributeString(int kind) {
212
250
throw new InternalError (
213
251
"Invalid jimage attribute kind: " + kind );
214
252
}
215
-
216
253
return getStrings ().get ((int )attributes [kind ]);
217
254
}
218
255
0 commit comments