Skip to content

Commit 9c5f0dd

Browse files
committed
Merge
2 parents 94dfb3e + d3b1c2b commit 9c5f0dd

File tree

22 files changed

+709
-159
lines changed

22 files changed

+709
-159
lines changed

make/data/currency/CurrencyData.properties

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ formatVersion=3
3232
# Version of the currency code information in this class.
3333
# It is a serial number that accompanies with each amendment.
3434

35-
dataVersion=179
35+
dataVersion=180
3636

3737
# List of all valid ISO 4217 currency codes.
3838
# To ensure compatibility, do not remove codes.
@@ -147,7 +147,7 @@ IO=USD
147147
# BRUNEI DARUSSALAM
148148
BN=BND
149149
# BULGARIA
150-
BG=BGN
150+
BG=BGN;2025-12-31-22-00-00;EUR
151151
# BURKINA FASO
152152
BF=XOF
153153
# BURUNDI
@@ -193,7 +193,7 @@ HR=EUR
193193
# CUBA
194194
CU=CUP
195195
# Cura\u00e7ao
196-
CW=ANG;2025-04-01-04-00-00;XCG
196+
CW=XCG
197197
# CYPRUS
198198
CY=EUR
199199
# CZECHIA
@@ -510,7 +510,7 @@ SR=SRD
510510
# SVALBARD AND JAN MAYEN
511511
SJ=NOK
512512
# Sint Maarten (Dutch part)
513-
SX=ANG;2025-04-01-04-00-00;XCG
513+
SX=XCG
514514
# ESWATINI
515515
SZ=SZL
516516
# SWEDEN

src/hotspot/share/classfile/stackMapTable.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,16 @@ bool StackMapTable::match_stackmap(
122122
}
123123

124124
void StackMapTable::check_jump_target(
125-
StackMapFrame* frame, int32_t target, TRAPS) const {
125+
StackMapFrame* frame, int bci, int offset, TRAPS) const {
126126
ErrorContext ctx;
127+
// Jump targets must be within the method and the method size is limited. See JVMS 4.11
128+
int min_offset = -1 * max_method_code_size;
129+
if (offset < min_offset || offset > max_method_code_size) {
130+
frame->verifier()->verify_error(ErrorContext::bad_stackmap(bci, frame),
131+
"Illegal target of jump or branch (bci %d + offset %d)", bci, offset);
132+
return;
133+
}
134+
int target = bci + offset;
127135
bool match = match_stackmap(
128136
frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
129137
if (!match || (target < 0 || target >= _code_length)) {

src/hotspot/share/classfile/stackMapTable.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class StackMapTable : public StackObj {
6969

7070
// Check jump instructions. Make sure there are no uninitialized
7171
// instances on backward branch.
72-
void check_jump_target(StackMapFrame* frame, int32_t target, TRAPS) const;
72+
void check_jump_target(StackMapFrame* frame, int bci, int offset, TRAPS) const;
7373

7474
// The following methods are only used inside this class.
7575

src/hotspot/share/classfile/verifier.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,6 @@ void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
717717
// Merge with the next instruction
718718
{
719719
u2 index;
720-
int target;
721720
VerificationType type, type2;
722721
VerificationType atype;
723722

@@ -1534,9 +1533,8 @@ void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
15341533
case Bytecodes::_ifle:
15351534
current_frame.pop_stack(
15361535
VerificationType::integer_type(), CHECK_VERIFY(this));
1537-
target = bcs.dest();
15381536
stackmap_table.check_jump_target(
1539-
&current_frame, target, CHECK_VERIFY(this));
1537+
&current_frame, bcs.bci(), bcs.get_offset_s2(), CHECK_VERIFY(this));
15401538
no_control_flow = false; break;
15411539
case Bytecodes::_if_acmpeq :
15421540
case Bytecodes::_if_acmpne :
@@ -1547,19 +1545,16 @@ void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
15471545
case Bytecodes::_ifnonnull :
15481546
current_frame.pop_stack(
15491547
VerificationType::reference_check(), CHECK_VERIFY(this));
1550-
target = bcs.dest();
15511548
stackmap_table.check_jump_target
1552-
(&current_frame, target, CHECK_VERIFY(this));
1549+
(&current_frame, bcs.bci(), bcs.get_offset_s2(), CHECK_VERIFY(this));
15531550
no_control_flow = false; break;
15541551
case Bytecodes::_goto :
1555-
target = bcs.dest();
15561552
stackmap_table.check_jump_target(
1557-
&current_frame, target, CHECK_VERIFY(this));
1553+
&current_frame, bcs.bci(), bcs.get_offset_s2(), CHECK_VERIFY(this));
15581554
no_control_flow = true; break;
15591555
case Bytecodes::_goto_w :
1560-
target = bcs.dest_w();
15611556
stackmap_table.check_jump_target(
1562-
&current_frame, target, CHECK_VERIFY(this));
1557+
&current_frame, bcs.bci(), bcs.get_offset_s4(), CHECK_VERIFY(this));
15631558
no_control_flow = true; break;
15641559
case Bytecodes::_tableswitch :
15651560
case Bytecodes::_lookupswitch :
@@ -2208,15 +2203,14 @@ void ClassVerifier::verify_switch(
22082203
}
22092204
}
22102205
}
2211-
int target = bci + default_offset;
2212-
stackmap_table->check_jump_target(current_frame, target, CHECK_VERIFY(this));
2206+
stackmap_table->check_jump_target(current_frame, bci, default_offset, CHECK_VERIFY(this));
22132207
for (int i = 0; i < keys; i++) {
22142208
// Because check_jump_target() may safepoint, the bytecode could have
22152209
// moved, which means 'aligned_bcp' is no good and needs to be recalculated.
22162210
aligned_bcp = align_up(bcs->bcp() + 1, jintSize);
2217-
target = bci + (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
2211+
int offset = (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
22182212
stackmap_table->check_jump_target(
2219-
current_frame, target, CHECK_VERIFY(this));
2213+
current_frame, bci, offset, CHECK_VERIFY(this));
22202214
}
22212215
NOT_PRODUCT(aligned_bcp = NULL); // no longer valid at this point
22222216
}
@@ -2479,8 +2473,13 @@ bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) {
24792473
break;
24802474

24812475
case Bytecodes::_goto:
2482-
case Bytecodes::_goto_w:
2483-
target = (opcode == Bytecodes::_goto ? bcs.dest() : bcs.dest_w());
2476+
case Bytecodes::_goto_w: {
2477+
int offset = (opcode == Bytecodes::_goto ? bcs.get_offset_s2() : bcs.get_offset_s4());
2478+
int min_offset = -1 * max_method_code_size;
2479+
// Check offset for overflow
2480+
if (offset < min_offset || offset > max_method_code_size) return false;
2481+
2482+
target = bci + offset;
24842483
if (visited_branches->contains(bci)) {
24852484
if (bci_stack->is_empty()) {
24862485
if (handler_stack->is_empty()) {
@@ -2501,6 +2500,7 @@ bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) {
25012500
visited_branches->append(bci);
25022501
}
25032502
break;
2503+
}
25042504

25052505
// Check that all switch alternatives end in 'athrow' bytecodes. Since it
25062506
// is difficult to determine where each switch alternative ends, parse
@@ -2537,7 +2537,10 @@ bool ClassVerifier::ends_in_athrow(u4 start_bc_offset) {
25372537

25382538
// Push the switch alternatives onto the stack.
25392539
for (int i = 0; i < keys; i++) {
2540-
u4 target = bci + (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
2540+
int min_offset = -1 * max_method_code_size;
2541+
int offset = (jint)Bytes::get_Java_u4(aligned_bcp+(3+i*delta)*jintSize);
2542+
if (offset < min_offset || offset > max_method_code_size) return false;
2543+
u4 target = bci + offset;
25412544
if (target > code_length) return false;
25422545
bci_stack->push(target);
25432546
}

src/hotspot/share/interpreter/bytecodeStream.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,23 @@ class BaseBytecodeStream: StackObj {
100100
void set_next_bci(int bci) { assert(0 <= bci && bci <= method()->code_size(), "illegal bci"); _next_bci = bci; }
101101

102102
// Bytecode-specific attributes
103-
int dest() const { return bci() + bytecode().get_offset_s2(raw_code()); }
104-
int dest_w() const { return bci() + bytecode().get_offset_s4(raw_code()); }
103+
int get_offset_s2() const { return bytecode().get_offset_s2(raw_code()); }
104+
int get_offset_s4() const { return bytecode().get_offset_s4(raw_code()); }
105+
106+
// These methods are not safe to use before or during verification as they may
107+
// have large offsets and cause overflows
108+
int dest() const {
109+
int min_offset = -1 * max_method_code_size;
110+
int offset = bytecode().get_offset_s2(raw_code());
111+
guarantee(offset >= min_offset && offset <= max_method_code_size, "must be");
112+
return bci() + offset;
113+
}
114+
int dest_w() const {
115+
int min_offset = -1 * max_method_code_size;
116+
int offset = bytecode().get_offset_s4(raw_code());
117+
guarantee(offset >= min_offset && offset <= max_method_code_size, "must be");
118+
return bci() + offset;
119+
}
105120

106121
// One-byte indices.
107122
int get_index_u1() const { assert_raw_index_size(1); return *(jubyte*)(bcp()+1); }

src/java.base/share/classes/sun/security/util/DerValue.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,22 @@ public boolean equals(Object o) {
821821
doEquals(other, this);
822822
}
823823

824+
/**
825+
* Checks that the BMPString does not contain any surrogate characters,
826+
* which are outside the Basic Multilingual Plane.
827+
*
828+
* @throws IOException if illegal characters are detected
829+
*/
830+
public void validateBMPString() throws IOException {
831+
String bmpString = getBMPString();
832+
for (int i = 0; i < bmpString.length(); i++) {
833+
if (Character.isSurrogate(bmpString.charAt(i))) {
834+
throw new IOException(
835+
"Illegal character in BMPString, index: " + i);
836+
}
837+
}
838+
}
839+
824840
/**
825841
* Helper for public method equals()
826842
*/

src/java.base/share/classes/sun/security/x509/AVA.java

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,9 +30,14 @@
3030
import java.io.OutputStream;
3131
import java.io.Reader;
3232
import java.security.AccessController;
33+
import java.nio.charset.Charset;
3334
import java.text.Normalizer;
3435
import java.util.*;
3536

37+
import static java.nio.charset.StandardCharsets.ISO_8859_1;
38+
import static java.nio.charset.StandardCharsets.UTF_8;
39+
import static java.nio.charset.StandardCharsets.UTF_16BE;
40+
3641
import sun.security.action.GetBooleanAction;
3742
import sun.security.util.*;
3843
import sun.security.pkcs.PKCS9Attribute;
@@ -606,6 +611,10 @@ private static boolean trailingSpace(Reader in) throws IOException {
606611
throw new IOException("AVA, extra bytes = "
607612
+ derval.data.available());
608613
}
614+
615+
if (value.tag == DerValue.tag_BMPString) {
616+
value.validateBMPString();
617+
}
609618
}
610619

611620
AVA(DerInputStream in) throws IOException {
@@ -753,7 +762,7 @@ public String toRFC2253String(Map<String, String> oidMap) {
753762
*/
754763
String valStr = null;
755764
try {
756-
valStr = new String(value.getDataBytes(), "UTF8");
765+
valStr = new String(value.getDataBytes(), getCharset(value, false));
757766
} catch (IOException ie) {
758767
throw new IllegalArgumentException("DER Value conversion");
759768
}
@@ -906,7 +915,7 @@ public String toRFC2253CanonicalString() {
906915
*/
907916
String valStr = null;
908917
try {
909-
valStr = new String(value.getDataBytes(), "UTF8");
918+
valStr = new String(value.getDataBytes(), getCharset(value, true));
910919
} catch (IOException ie) {
911920
throw new IllegalArgumentException("DER Value conversion");
912921
}
@@ -1026,6 +1035,46 @@ private static boolean isDerString(DerValue value, boolean canonical) {
10261035
}
10271036
}
10281037

1038+
/*
1039+
* Returns the charset that should be used to decode each DN string type.
1040+
*
1041+
* This method ensures that multi-byte (UTF8String and BMPString) types
1042+
* are decoded using the correct charset and the String forms represent
1043+
* the correct characters. For 8-bit ASCII-based types (PrintableString
1044+
* and IA5String), we return ISO_8859_1 rather than ASCII, so that the
1045+
* complete range of characters can be represented, as many certificates
1046+
* do not comply with the Internationalized Domain Name ACE format.
1047+
*
1048+
* NOTE: this method only supports DirectoryStrings of the types returned
1049+
* by isDerString().
1050+
*/
1051+
private static Charset getCharset(DerValue value, boolean canonical) {
1052+
if (canonical) {
1053+
switch (value.tag) {
1054+
case DerValue.tag_PrintableString:
1055+
return ISO_8859_1;
1056+
case DerValue.tag_UTF8String:
1057+
return UTF_8;
1058+
default:
1059+
throw new Error("unexpected tag: " + value.tag);
1060+
}
1061+
}
1062+
1063+
switch (value.tag) {
1064+
case DerValue.tag_PrintableString:
1065+
case DerValue.tag_T61String:
1066+
case DerValue.tag_IA5String:
1067+
case DerValue.tag_GeneralString:
1068+
return ISO_8859_1;
1069+
case DerValue.tag_BMPString:
1070+
return UTF_16BE;
1071+
case DerValue.tag_UTF8String:
1072+
return UTF_8;
1073+
default:
1074+
throw new Error("unexpected tag: " + value.tag);
1075+
}
1076+
}
1077+
10291078
boolean hasRFC2253Keyword() {
10301079
return AVAKeyword.hasKeyword(oid, RFC2253);
10311080
}

src/java.base/share/native/libverify/check_code.c

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ static jboolean is_superclass(context_type *, fullinfo_type);
398398

399399
static void initialize_exception_table(context_type *);
400400
static int instruction_length(unsigned char *iptr, unsigned char *end);
401-
static jboolean isLegalTarget(context_type *, int offset);
401+
static jboolean isLegalOffset(context_type *, int bci, int offset);
402+
static jboolean isLegalTarget(context_type *, int target);
402403
static void verify_constant_pool_type(context_type *, int, unsigned);
403404

404405
static void initialize_dataflow(context_type *);
@@ -1169,9 +1170,9 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
11691170
case JVM_OPC_goto: {
11701171
/* Set the ->operand to be the instruction number of the target. */
11711172
int jump = (((signed char)(code[offset+1])) << 8) + code[offset+2];
1172-
int target = offset + jump;
1173-
if (!isLegalTarget(context, target))
1173+
if (!isLegalOffset(context, offset, jump))
11741174
CCerror(context, "Illegal target of jump or branch");
1175+
int target = offset + jump;
11751176
this_idata->operand.i = code_data[target];
11761177
break;
11771178
}
@@ -1185,9 +1186,9 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
11851186
int jump = (((signed char)(code[offset+1])) << 24) +
11861187
(code[offset+2] << 16) + (code[offset+3] << 8) +
11871188
(code[offset + 4]);
1188-
int target = offset + jump;
1189-
if (!isLegalTarget(context, target))
1189+
if (!isLegalOffset(context, offset, jump))
11901190
CCerror(context, "Illegal target of jump or branch");
1191+
int target = offset + jump;
11911192
this_idata->operand.i = code_data[target];
11921193
break;
11931194
}
@@ -1226,13 +1227,16 @@ verify_opcode_operands(context_type *context, unsigned int inumber, int offset)
12261227
}
12271228
}
12281229
saved_operand = NEW(int, keys + 2);
1229-
if (!isLegalTarget(context, offset + _ck_ntohl(lpc[0])))
1230+
int jump = _ck_ntohl(lpc[0]);
1231+
if (!isLegalOffset(context, offset, jump))
12301232
CCerror(context, "Illegal default target in switch");
1231-
saved_operand[keys + 1] = code_data[offset + _ck_ntohl(lpc[0])];
1233+
int target = offset + jump;
1234+
saved_operand[keys + 1] = code_data[target];
12321235
for (k = keys, lptr = &lpc[3]; --k >= 0; lptr += delta) {
1233-
int target = offset + _ck_ntohl(lptr[0]);
1234-
if (!isLegalTarget(context, target))
1236+
jump = _ck_ntohl(lptr[0]);
1237+
if (!isLegalOffset(context, offset, jump))
12351238
CCerror(context, "Illegal branch in tableswitch");
1239+
target = offset + jump;
12361240
saved_operand[k + 1] = code_data[target];
12371241
}
12381242
saved_operand[0] = keys + 1; /* number of successors */
@@ -1756,11 +1760,24 @@ static int instruction_length(unsigned char *iptr, unsigned char *end)
17561760

17571761
/* Given the target of a branch, make sure that it's a legal target. */
17581762
static jboolean
1759-
isLegalTarget(context_type *context, int offset)
1763+
isLegalTarget(context_type *context, int target)
1764+
{
1765+
int code_length = context->code_length;
1766+
int *code_data = context->code_data;
1767+
return (target >= 0 && target < code_length && code_data[target] >= 0);
1768+
}
1769+
1770+
/* Given a bci and offset, make sure the offset is valid and the target is legal */
1771+
static jboolean
1772+
isLegalOffset(context_type *context, int bci, int offset)
17601773
{
17611774
int code_length = context->code_length;
17621775
int *code_data = context->code_data;
1763-
return (offset >= 0 && offset < code_length && code_data[offset] >= 0);
1776+
int max_offset = 65535; // JVMS 4.11
1777+
int min_offset = -65535;
1778+
if (offset < min_offset || offset > max_offset) return JNI_FALSE;
1779+
int target = bci + offset;
1780+
return (target >= 0 && target < code_length && code_data[target] >= 0);
17641781
}
17651782

17661783

0 commit comments

Comments
 (0)