Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/native/common/check_format.c
38825 views
1
/*
2
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include <setjmp.h>
27
#include <stdlib.h>
28
#include <string.h>
29
30
#include "jni.h"
31
#include "jvm.h"
32
33
typedef unsigned short unicode;
34
35
static char *
36
skip_over_fieldname(char *name, jboolean slash_okay,
37
unsigned int len);
38
static char *
39
skip_over_field_signature(char *name, jboolean void_okay,
40
unsigned int len);
41
42
/*
43
* Return non-zero if the character is a valid in JVM class name, zero
44
* otherwise. The only characters currently disallowed from JVM class
45
* names are given in the table below:
46
*
47
* Character Hex Decimal
48
* '.' 0x2e 46
49
* '/' 0x2f 47
50
* ';' 0x3b 59
51
* '[' 0x5b 91
52
*
53
* (Method names have further restrictions dealing with the '<' and
54
* '>' characters.)
55
*/
56
static int isJvmIdentifier(unicode ch) {
57
if( ch > 91 || ch < 46 )
58
return 1; /* Lowercase ASCII letters are > 91 */
59
else { /* 46 <= ch <= 91 */
60
if (ch <= 90 && ch >= 60) {
61
return 1; /* Uppercase ASCII recognized here */
62
} else { /* ch == 91 || 46 <= ch <= 59 */
63
if (ch == 91 || ch == 59 || ch <= 47)
64
return 0;
65
else
66
return 1;
67
}
68
}
69
}
70
71
static unicode
72
next_utf2unicode(char **utfstring_ptr, int * valid)
73
{
74
unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
75
unsigned char ch, ch2, ch3;
76
int length = 1; /* default length */
77
unicode result = 0x80; /* default bad result; */
78
*valid = 1;
79
switch ((ch = ptr[0]) >> 4) {
80
default:
81
result = ch;
82
break;
83
84
case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
85
/* Shouldn't happen. */
86
*valid = 0;
87
break;
88
89
case 0xC: case 0xD:
90
/* 110xxxxx 10xxxxxx */
91
if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
92
unsigned char high_five = ch & 0x1F;
93
unsigned char low_six = ch2 & 0x3F;
94
result = (high_five << 6) + low_six;
95
length = 2;
96
}
97
break;
98
99
case 0xE:
100
/* 1110xxxx 10xxxxxx 10xxxxxx */
101
if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
102
if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
103
unsigned char high_four = ch & 0x0f;
104
unsigned char mid_six = ch2 & 0x3f;
105
unsigned char low_six = ch3 & 0x3f;
106
result = (((high_four << 6) + mid_six) << 6) + low_six;
107
length = 3;
108
} else {
109
length = 2;
110
}
111
}
112
break;
113
} /* end of switch */
114
115
*utfstring_ptr = (char *)(ptr + length);
116
return result;
117
}
118
119
/* Take pointer to a string. Skip over the longest part of the string that
120
* could be taken as a fieldname. Allow '/' if slash_okay is JNI_TRUE.
121
*
122
* Return a pointer to just past the fieldname. Return NULL if no fieldname
123
* at all was found, or in the case of slash_okay being true, we saw
124
* consecutive slashes (meaning we were looking for a qualified path but
125
* found something that was badly-formed).
126
*/
127
static char *
128
skip_over_fieldname(char *name, jboolean slash_okay,
129
unsigned int length)
130
{
131
char *p;
132
unicode ch;
133
unicode last_ch = 0;
134
int valid = 1;
135
/* last_ch == 0 implies we are looking at the first char. */
136
for (p = name; p != name + length; last_ch = ch) {
137
char *old_p = p;
138
ch = *p;
139
if (ch < 128) {
140
p++;
141
if (isJvmIdentifier(ch)) {
142
continue;
143
}
144
} else {
145
char *tmp_p = p;
146
ch = next_utf2unicode(&tmp_p, &valid);
147
if (valid == 0)
148
return 0;
149
p = tmp_p;
150
if (isJvmIdentifier(ch)) {
151
continue;
152
}
153
}
154
155
if (slash_okay && ch == '/' && last_ch) {
156
if (last_ch == '/') {
157
return 0; /* Don't permit consecutive slashes */
158
}
159
} else if (ch == '_' || ch == '$') {
160
} else {
161
return last_ch ? old_p : 0;
162
}
163
}
164
return last_ch ? p : 0;
165
}
166
167
/* Take pointer to a string. Skip over the longest part of the string that
168
* could be taken as a field signature. Allow "void" if void_okay.
169
*
170
* Return a pointer to just past the signature. Return NULL if no legal
171
* signature is found.
172
*/
173
174
static char *
175
skip_over_field_signature(char *name, jboolean void_okay,
176
unsigned int length)
177
{
178
unsigned int array_dim = 0;
179
for (;length > 0;) {
180
switch (name[0]) {
181
case JVM_SIGNATURE_VOID:
182
if (!void_okay) return 0;
183
/* FALL THROUGH */
184
case JVM_SIGNATURE_BOOLEAN:
185
case JVM_SIGNATURE_BYTE:
186
case JVM_SIGNATURE_CHAR:
187
case JVM_SIGNATURE_SHORT:
188
case JVM_SIGNATURE_INT:
189
case JVM_SIGNATURE_FLOAT:
190
case JVM_SIGNATURE_LONG:
191
case JVM_SIGNATURE_DOUBLE:
192
return name + 1;
193
194
case JVM_SIGNATURE_CLASS: {
195
/* Skip over the classname, if one is there. */
196
char *p =
197
skip_over_fieldname(name + 1, JNI_TRUE, --length);
198
/* The next character better be a semicolon. */
199
if (p && p - name - 1 > 0 && p[0] == ';')
200
return p + 1;
201
return 0;
202
}
203
204
case JVM_SIGNATURE_ARRAY:
205
array_dim++;
206
/* JVMS 2nd ed. 4.10 */
207
/* The number of dimensions in an array is limited to 255 ... */
208
if (array_dim > 255) {
209
return 0;
210
}
211
/* The rest of what's there better be a legal signature. */
212
name++;
213
length--;
214
void_okay = JNI_FALSE;
215
break;
216
217
default:
218
return 0;
219
}
220
}
221
return 0;
222
}
223
224
225
/* Used in java/lang/Class.c */
226
/* Determine if the specified name is legal
227
* UTF name for a classname.
228
*
229
* Note that this routine expects the internal form of qualified classes:
230
* the dots should have been replaced by slashes.
231
*/
232
JNIEXPORT jboolean
233
VerifyClassname(char *name, jboolean allowArrayClass)
234
{
235
unsigned int length = strlen(name);
236
char *p;
237
238
if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
239
if (!allowArrayClass) {
240
return JNI_FALSE;
241
} else {
242
/* Everything that's left better be a field signature */
243
p = skip_over_field_signature(name, JNI_FALSE, length);
244
}
245
} else {
246
/* skip over the fieldname. Slashes are okay */
247
p = skip_over_fieldname(name, JNI_TRUE, length);
248
}
249
return (p != 0 && p - name == (ptrdiff_t)length);
250
}
251
252
/*
253
* Translates '.' to '/'. Returns JNI_TRUE is any / were present.
254
*/
255
JNIEXPORT jboolean
256
VerifyFixClassname(char *name)
257
{
258
char *p = name;
259
jboolean slashesFound = JNI_FALSE;
260
int valid = 1;
261
262
while (valid != 0 && *p != '\0') {
263
if (*p == '/') {
264
slashesFound = JNI_TRUE;
265
p++;
266
} else if (*p == '.') {
267
*p++ = '/';
268
} else {
269
next_utf2unicode(&p, &valid);
270
}
271
}
272
273
return slashesFound && valid != 0;
274
}
275
276