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/bin/version_comp.c
38767 views
1
/*
2
* Copyright (c) 2003, 2006, 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 <ctype.h>
27
#include <stdlib.h>
28
#include <string.h>
29
#include <sys/types.h>
30
#include "jni.h"
31
#include "jli_util.h"
32
#include "version_comp.h"
33
34
/*
35
* A collection of useful strings. One should think of these as #define
36
* entries, but actual strings can be more efficient (with many compilers).
37
*/
38
static const char *separators = ".-_";
39
static const char *zero_string = "0";
40
41
/*
42
* Validate a string as parsable as a "Java int". If so parsable,
43
* return true (non-zero) and store the numeric value at the address
44
* passed in as "value"; otherwise return false (zero).
45
*
46
* Note that the maximum allowable value is 2147483647 as defined by
47
* the "Java Language Specification" which precludes the use of native
48
* conversion routines which may have other limits.
49
*
50
* Also note that we don't have to worry about the alternate maximum
51
* allowable value of 2147483648 because it is only allowed after
52
* the unary negation operator and this grammar doesn't have one
53
* of those.
54
*
55
* Finally, note that a value which exceeds the maximum jint value will
56
* return false (zero). This results in the otherwise purely numeric
57
* string being compared as a string of characters (as per the spec.)
58
*/
59
static int
60
isjavaint(const char *s, jint *value)
61
{
62
jlong sum = 0;
63
jint digit;
64
while (*s != '\0')
65
if (isdigit(*s)) {
66
digit = (jint)((int)(*s++) - (int)('0'));
67
sum = (sum * 10) + digit;
68
if (sum > 2147483647)
69
return (0); /* Overflows jint (but not jlong) */
70
} else
71
return (0);
72
*value = (jint)sum;
73
return (1);
74
}
75
76
/*
77
* Modeled after strcmp(), compare two strings (as in the grammar defined
78
* in Appendix A of JSR 56). If both strings can be interpreted as
79
* Java ints, do a numeric comparison, else it is strcmp().
80
*/
81
static int
82
comp_string(const char *s1, const char *s2)
83
{
84
jint v1, v2;
85
if (isjavaint(s1, &v1) && isjavaint(s2, &v2))
86
return ((int)(v1 - v2));
87
else
88
return (JLI_StrCmp(s1, s2));
89
}
90
91
/*
92
* Modeled after strcmp(), compare two version-ids for a Prefix
93
* Match as defined in JSR 56.
94
*/
95
int
96
JLI_PrefixVersionId(const char *id1, char *id2)
97
{
98
char *s1 = JLI_StringDup(id1);
99
char *s2 = JLI_StringDup(id2);
100
char *m1 = s1;
101
char *m2 = s2;
102
char *end1 = NULL;
103
char *end2 = NULL;
104
int res = 0;
105
106
do {
107
108
if ((s1 != NULL) && ((end1 = JLI_StrPBrk(s1, ".-_")) != NULL))
109
*end1 = '\0';
110
if ((s2 != NULL) && ((end2 = JLI_StrPBrk(s2, ".-_")) != NULL))
111
*end2 = '\0';
112
113
res = comp_string(s1, s2);
114
115
if (end1 != NULL)
116
s1 = end1 + 1;
117
else
118
s1 = NULL;
119
if (end2 != NULL)
120
s2 = end2 + 1;
121
else
122
s2 = NULL;
123
124
} while (res == 0 && ((s1 != NULL) && (s2 != NULL)));
125
126
JLI_MemFree(m1);
127
JLI_MemFree(m2);
128
return (res);
129
}
130
131
/*
132
* Modeled after strcmp(), compare two version-ids for an Exact
133
* Match as defined in JSR 56.
134
*/
135
int
136
JLI_ExactVersionId(const char *id1, char *id2)
137
{
138
char *s1 = JLI_StringDup(id1);
139
char *s2 = JLI_StringDup(id2);
140
char *m1 = s1;
141
char *m2 = s2;
142
char *end1 = NULL;
143
char *end2 = NULL;
144
int res = 0;
145
146
do {
147
148
if ((s1 != NULL) && ((end1 = JLI_StrPBrk(s1, separators)) != NULL))
149
*end1 = '\0';
150
if ((s2 != NULL) && ((end2 = JLI_StrPBrk(s2, separators)) != NULL))
151
*end2 = '\0';
152
153
if ((s1 != NULL) && (s2 == NULL))
154
res = comp_string(s1, zero_string);
155
else if ((s1 == NULL) && (s2 != NULL))
156
res = comp_string(zero_string, s2);
157
else
158
res = comp_string(s1, s2);
159
160
if (end1 != NULL)
161
s1 = end1 + 1;
162
else
163
s1 = NULL;
164
if (end2 != NULL)
165
s2 = end2 + 1;
166
else
167
s2 = NULL;
168
169
} while (res == 0 && ((s1 != NULL) || (s2 != NULL)));
170
171
JLI_MemFree(m1);
172
JLI_MemFree(m2);
173
return (res);
174
}
175
176
/*
177
* Return true if this simple-element (as defined in JSR 56) forms
178
* an acceptable match.
179
*
180
* JSR 56 is modified by the Java Web Start <rel> Developer Guide
181
* where it is stated "... Java Web Start will not consider an installed
182
* non-FCS (i.e., milestone) JRE as a match. ... a JRE from Sun
183
* Microsystems, Inc., is by convention a non-FCS (milestone) JRE
184
* if there is a dash (-) in the version string."
185
*
186
* An undocumented caveat to the above is that an exact match with a
187
* hyphen is accepted as a development extension.
188
*
189
* These modifications are addressed by the specific comparisons
190
* for releases with hyphens.
191
*/
192
static int
193
acceptable_simple_element(const char *release, char *simple_element)
194
{
195
char *modifier;
196
modifier = simple_element + JLI_StrLen(simple_element) - 1;
197
if (*modifier == '*') {
198
*modifier = '\0';
199
if (JLI_StrChr(release, '-'))
200
return ((JLI_StrCmp(release, simple_element) == 0)?1:0);
201
return ((JLI_PrefixVersionId(release, simple_element) == 0)?1:0);
202
} else if (*modifier == '+') {
203
*modifier = '\0';
204
if (JLI_StrChr(release, '-'))
205
return ((JLI_StrCmp(release, simple_element) == 0)?1:0);
206
return ((JLI_ExactVersionId(release, simple_element) >= 0)?1:0);
207
} else {
208
return ((JLI_ExactVersionId(release, simple_element) == 0)?1:0);
209
}
210
}
211
212
/*
213
* Return true if this element (as defined in JSR 56) forms
214
* an acceptable match. An element is the intersection (and)
215
* of multiple simple-elements.
216
*/
217
static int
218
acceptable_element(const char *release, char *element)
219
{
220
char *end;
221
do {
222
if ((end = JLI_StrChr(element, '&')) != NULL)
223
*end = '\0';
224
if (!acceptable_simple_element(release, element))
225
return (0);
226
if (end != NULL)
227
element = end + 1;
228
} while (end != NULL);
229
return (1);
230
}
231
232
/*
233
* Checks if release is acceptable by the specification version-string.
234
* Return true if this version-string (as defined in JSR 56) forms
235
* an acceptable match. A version-string is the union (or) of multiple
236
* elements.
237
*/
238
int
239
JLI_AcceptableRelease(const char *release, char *version_string)
240
{
241
char *vs;
242
char *m1;
243
char *end;
244
m1 = vs = JLI_StringDup(version_string);
245
do {
246
if ((end = JLI_StrChr(vs, ' ')) != NULL)
247
*end = '\0';
248
if (acceptable_element(release, vs)) {
249
JLI_MemFree(m1);
250
return (1);
251
}
252
if (end != NULL)
253
vs = end + 1;
254
} while (end != NULL);
255
JLI_MemFree(m1);
256
return (0);
257
}
258
259
/*
260
* Return true if this is a valid simple-element (as defined in JSR 56).
261
*
262
* The official grammar for a simple-element is:
263
*
264
* simple-element ::= version-id | version-id modifier
265
* modifier ::= '+' | '*'
266
* version-id ::= string ( separator string )*
267
* string ::= char ( char )*
268
* char ::= Any ASCII character except a space, an
269
* ampersand, a separator or a modifier
270
* separator ::= '.' | '-' | '_'
271
*
272
* However, for efficiency, it is time to abandon the top down parser
273
* implementation. After deleting the potential trailing modifier, we
274
* are left with a version-id.
275
*
276
* Note that a valid version-id has three simple properties:
277
*
278
* 1) Doesn't contain a space, an ampersand or a modifier.
279
*
280
* 2) Doesn't begin or end with a separator.
281
*
282
* 3) Doesn't contain two adjacent separators.
283
*
284
* Any other line noise constitutes a valid version-id.
285
*/
286
static int
287
valid_simple_element(char *simple_element)
288
{
289
char *last;
290
size_t len;
291
292
if ((simple_element == NULL) || ((len = JLI_StrLen(simple_element)) == 0))
293
return (0);
294
last = simple_element + len - 1;
295
if (*last == '*' || *last == '+') {
296
if (--len == 0)
297
return (0);
298
*last-- = '\0';
299
}
300
if (JLI_StrPBrk(simple_element, " &+*") != NULL) /* Property #1 */
301
return (0);
302
if ((JLI_StrChr(".-_", *simple_element) != NULL) || /* Property #2 */
303
(JLI_StrChr(".-_", *last) != NULL))
304
return (0);
305
for (; simple_element != last; simple_element++) /* Property #3 */
306
if ((JLI_StrChr(".-_", *simple_element) != NULL) &&
307
(JLI_StrChr(".-_", *(simple_element + 1)) != NULL))
308
return (0);
309
return (1);
310
}
311
312
/*
313
* Return true if this is a valid element (as defined in JSR 56).
314
* An element is the intersection (and) of multiple simple-elements.
315
*/
316
static int
317
valid_element(char *element)
318
{
319
char *end;
320
if ((element == NULL) || (JLI_StrLen(element) == 0))
321
return (0);
322
do {
323
if ((end = JLI_StrChr(element, '&')) != NULL)
324
*end = '\0';
325
if (!valid_simple_element(element))
326
return (0);
327
if (end != NULL)
328
element = end + 1;
329
} while (end != NULL);
330
return (1);
331
}
332
333
/*
334
* Validates a version string by the extended JSR 56 grammar.
335
*/
336
int
337
JLI_ValidVersionString(char *version_string)
338
{
339
char *vs;
340
char *m1;
341
char *end;
342
if ((version_string == NULL) || (JLI_StrLen(version_string) == 0))
343
return (0);
344
m1 = vs = JLI_StringDup(version_string);
345
do {
346
if ((end = JLI_StrChr(vs, ' ')) != NULL)
347
*end = '\0';
348
if (!valid_element(vs)) {
349
JLI_MemFree(m1);
350
return (0);
351
}
352
if (end != NULL)
353
vs = end + 1;
354
} while (end != NULL);
355
JLI_MemFree(m1);
356
return (1);
357
}
358
359