Skip to content

Commit 39c17b3

Browse files
committed
8341277: Validate slot argument for instruction factories
Reviewed-by: asotona
1 parent 0f38113 commit 39c17b3

15 files changed

+366
-80
lines changed

src/java.base/share/classes/java/lang/classfile/CodeBuilder.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,8 @@ default CodeBuilder trying(Consumer<BlockCodeBuilder> tryHandler,
429429
* @param tk the load type
430430
* @param slot the local variable slot
431431
* @return this builder
432+
* @throws IllegalArgumentException if {@code tk} is {@link TypeKind#VOID void}
433+
* or {@code slot} is out of range
432434
* @since 23
433435
*/
434436
default CodeBuilder loadLocal(TypeKind tk, int slot) {
@@ -440,6 +442,8 @@ default CodeBuilder loadLocal(TypeKind tk, int slot) {
440442
* @param tk the store type
441443
* @param slot the local variable slot
442444
* @return this builder
445+
* @throws IllegalArgumentException if {@code tk} is {@link TypeKind#VOID void}
446+
* or {@code slot} is out of range
443447
* @since 23
444448
*/
445449
default CodeBuilder storeLocal(TypeKind tk, int slot) {
@@ -793,6 +797,7 @@ default CodeBuilder characterRange(Label startScope, Label endScope, int charact
793797
* @param startScope the start scope of the variable
794798
* @param endScope the end scope of the variable
795799
* @return this builder
800+
* @throws IllegalArgumentException if {@code slot} is out of range
796801
*/
797802
default CodeBuilder localVariable(int slot, Utf8Entry nameEntry, Utf8Entry descriptorEntry, Label startScope, Label endScope) {
798803
return with(LocalVariable.of(slot, nameEntry, descriptorEntry, startScope, endScope));
@@ -806,6 +811,7 @@ default CodeBuilder localVariable(int slot, Utf8Entry nameEntry, Utf8Entry descr
806811
* @param startScope the start scope of the variable
807812
* @param endScope the end scope of the variable
808813
* @return this builder
814+
* @throws IllegalArgumentException if {@code slot} is out of range
809815
*/
810816
default CodeBuilder localVariable(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) {
811817
return localVariable(slot,
@@ -822,6 +828,7 @@ default CodeBuilder localVariable(int slot, String name, ClassDesc descriptor, L
822828
* @param startScope the start scope of the variable
823829
* @param endScope the end scope of the variable
824830
* @return this builder
831+
* @throws IllegalArgumentException if {@code slot} is out of range
825832
*/
826833
default CodeBuilder localVariableType(int slot, Utf8Entry nameEntry, Utf8Entry signatureEntry, Label startScope, Label endScope) {
827834
return with(LocalVariableType.of(slot, nameEntry, signatureEntry, startScope, endScope));
@@ -835,6 +842,7 @@ default CodeBuilder localVariableType(int slot, Utf8Entry nameEntry, Utf8Entry s
835842
* @param startScope the start scope of the variable
836843
* @param endScope the end scope of the variable
837844
* @return this builder
845+
* @throws IllegalArgumentException if {@code slot} is out of range
838846
*/
839847
default CodeBuilder localVariableType(int slot, String name, Signature signature, Label startScope, Label endScope) {
840848
return localVariableType(slot,
@@ -877,6 +885,7 @@ default CodeBuilder aastore() {
877885
*
878886
* @param slot the local variable slot
879887
* @return this builder
888+
* @throws IllegalArgumentException if {@code slot} is out of range
880889
*/
881890
default CodeBuilder aload(int slot) {
882891
return loadLocal(TypeKind.REFERENCE, slot);
@@ -925,6 +934,7 @@ default CodeBuilder arraylength() {
925934
*
926935
* @param slot the local variable slot
927936
* @return this builder
937+
* @throws IllegalArgumentException if {@code slot} is out of range
928938
*/
929939
default CodeBuilder astore(int slot) {
930940
return storeLocal(TypeKind.REFERENCE, slot);
@@ -958,6 +968,7 @@ default CodeBuilder bastore() {
958968
* Generate an instruction pushing an int in the range of byte onto the operand stack.
959969
* @param b the int in the range of byte
960970
* @return this builder
971+
* @throws IllegalArgumentException if {@code b} is out of range of byte
961972
*/
962973
default CodeBuilder bipush(int b) {
963974
return with(ConstantInstruction.ofArgument(Opcode.BIPUSH, b));
@@ -1094,6 +1105,7 @@ default CodeBuilder ddiv() {
10941105
*
10951106
* @param slot the local variable slot
10961107
* @return this builder
1108+
* @throws IllegalArgumentException if {@code slot} is out of range
10971109
*/
10981110
default CodeBuilder dload(int slot) {
10991111
return loadLocal(TypeKind.DOUBLE, slot);
@@ -1139,6 +1151,7 @@ default CodeBuilder dreturn() {
11391151
*
11401152
* @param slot the local variable slot
11411153
* @return this builder
1154+
* @throws IllegalArgumentException if {@code slot} is out of range
11421155
*/
11431156
default CodeBuilder dstore(int slot) {
11441157
return storeLocal(TypeKind.DOUBLE, slot);
@@ -1306,6 +1319,7 @@ default CodeBuilder fdiv() {
13061319
*
13071320
* @param slot the local variable slot
13081321
* @return this builder
1322+
* @throws IllegalArgumentException if {@code slot} is out of range
13091323
*/
13101324
default CodeBuilder fload(int slot) {
13111325
return loadLocal(TypeKind.FLOAT, slot);
@@ -1351,6 +1365,7 @@ default CodeBuilder freturn() {
13511365
*
13521366
* @param slot the local variable slot
13531367
* @return this builder
1368+
* @throws IllegalArgumentException if {@code slot} is out of range
13541369
*/
13551370
default CodeBuilder fstore(int slot) {
13561371
return storeLocal(TypeKind.FLOAT, slot);
@@ -1726,6 +1741,7 @@ default CodeBuilder ifne(Label target) {
17261741
* @param slot the local variable slot
17271742
* @param val the increment value
17281743
* @return this builder
1744+
* @throws IllegalArgumentException if {@code slot} or {@code val} is out of range
17291745
*/
17301746
default CodeBuilder iinc(int slot, int val) {
17311747
return with(IncrementInstruction.of(slot, val));
@@ -1739,6 +1755,7 @@ default CodeBuilder iinc(int slot, int val) {
17391755
*
17401756
* @param slot the local variable slot
17411757
* @return this builder
1758+
* @throws IllegalArgumentException if {@code slot} is out of range
17421759
*/
17431760
default CodeBuilder iload(int slot) {
17441761
return loadLocal(TypeKind.INT, slot);
@@ -1997,6 +2014,7 @@ default CodeBuilder ishr() {
19972014
*
19982015
* @param slot the local variable slot
19992016
* @return this builder
2017+
* @throws IllegalArgumentException if {@code slot} is out of range
20002018
*/
20012019
default CodeBuilder istore(int slot) {
20022020
return storeLocal(TypeKind.INT, slot);
@@ -2159,6 +2177,7 @@ default CodeBuilder ldiv() {
21592177
*
21602178
* @param slot the local variable slot
21612179
* @return this builder
2180+
* @throws IllegalArgumentException if {@code slot} is out of range
21622181
*/
21632182
default CodeBuilder lload(int slot) {
21642183
return loadLocal(TypeKind.LONG, slot);
@@ -2228,6 +2247,7 @@ default CodeBuilder lshr() {
22282247
*
22292248
* @param slot the local variable slot
22302249
* @return this builder
2250+
* @throws IllegalArgumentException if {@code slot} is out of range
22312251
*/
22322252
default CodeBuilder lstore(int slot) {
22332253
return storeLocal(TypeKind.LONG, slot);
@@ -2278,6 +2298,7 @@ default CodeBuilder monitorexit() {
22782298
* @param array the array type
22792299
* @param dims the number of dimensions
22802300
* @return this builder
2301+
* @throws IllegalArgumentException if {@code dims} is out of range
22812302
*/
22822303
default CodeBuilder multianewarray(ClassEntry array, int dims) {
22832304
return with(NewMultiArrayInstruction.of(array, dims));
@@ -2289,6 +2310,7 @@ default CodeBuilder multianewarray(ClassEntry array, int dims) {
22892310
* @param dims the number of dimensions
22902311
* @return this builder
22912312
* @throws IllegalArgumentException if {@code array} represents a primitive type
2313+
* or if {@code dims} is out of range
22922314
*/
22932315
default CodeBuilder multianewarray(ClassDesc array, int dims) {
22942316
return multianewarray(constantPool().classEntry(array), dims);
@@ -2327,6 +2349,8 @@ default CodeBuilder new_(ClassDesc clazz) {
23272349
* Generate an instruction to create a new array of a primitive type
23282350
* @param typeKind the primitive array type
23292351
* @return this builder
2352+
* @throws IllegalArgumentException when the {@code typeKind} is not a legal
2353+
* primitive array component type
23302354
*/
23312355
default CodeBuilder newarray(TypeKind typeKind) {
23322356
return with(NewPrimitiveArrayInstruction.of(typeKind));
@@ -2423,6 +2447,7 @@ default CodeBuilder sastore() {
24232447
* Generate an instruction pushing an int in the range of short onto the operand stack.
24242448
* @param s the int in the range of short
24252449
* @return this builder
2450+
* @throws IllegalArgumentException if {@code s} is out of range of short
24262451
*/
24272452
default CodeBuilder sipush(int s) {
24282453
return with(ConstantInstruction.ofArgument(Opcode.SIPUSH, s));

src/java.base/share/classes/java/lang/classfile/instruction/DiscontinuedInstruction.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.lang.classfile.Label;
3131
import java.lang.classfile.Opcode;
3232
import jdk.internal.classfile.impl.AbstractInstruction;
33+
import jdk.internal.classfile.impl.BytecodeHelpers;
3334
import jdk.internal.classfile.impl.Util;
3435
import jdk.internal.javac.PreviewFeature;
3536

@@ -112,17 +113,18 @@ sealed interface RetInstruction extends DiscontinuedInstruction
112113
* which must be of kind {@link Opcode.Kind#DISCONTINUED_RET}
113114
* @param slot the local variable slot to load return address from
114115
* @throws IllegalArgumentException if the opcode kind is not
115-
* {@link Opcode.Kind#DISCONTINUED_RET}.
116+
* {@link Opcode.Kind#DISCONTINUED_RET} or if {@code slot} is out of range
116117
*/
117118
static RetInstruction of(Opcode op, int slot) {
118-
Util.checkKind(op, Opcode.Kind.DISCONTINUED_RET);
119+
BytecodeHelpers.validateRet(op, slot);
119120
return new AbstractInstruction.UnboundRetInstruction(op, slot);
120121
}
121122

122123
/**
123124
* {@return a RET instruction}
124125
*
125126
* @param slot the local variable slot to load return address from
127+
* @throws IllegalArgumentException if {@code slot} is out of range
126128
*/
127129
static RetInstruction of(int slot) {
128130
return of(slot < 256 ? Opcode.RET : Opcode.RET_W, slot);

src/java.base/share/classes/java/lang/classfile/instruction/IncrementInstruction.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public sealed interface IncrementInstruction extends Instruction
5858
*
5959
* @param slot the local variable slot to increment
6060
* @param constant the value to increment by
61+
* @throws IllegalArgumentException if {@code slot} or {@code constant} is out of range
6162
*/
6263
static IncrementInstruction of(int slot, int constant) {
6364
return new AbstractInstruction.UnboundIncrementInstruction(slot, constant);

src/java.base/share/classes/java/lang/classfile/instruction/LoadInstruction.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,12 @@ public sealed interface LoadInstruction extends Instruction
6262
*
6363
* @param kind the type of the value to be loaded
6464
* @param slot the local variable slot to load from
65+
* @throws IllegalArgumentException if {@code kind} is
66+
* {@link TypeKind#VOID void} or {@code slot} is out of range
6567
*/
6668
static LoadInstruction of(TypeKind kind, int slot) {
67-
return of(BytecodeHelpers.loadOpcode(kind, slot), slot);
69+
var opcode = BytecodeHelpers.loadOpcode(kind, slot); // validates slot, trusted
70+
return new AbstractInstruction.UnboundLoadInstruction(opcode, slot);
6871
}
6972

7073
/**
@@ -74,10 +77,11 @@ static LoadInstruction of(TypeKind kind, int slot) {
7477
* which must be of kind {@link Opcode.Kind#LOAD}
7578
* @param slot the local variable slot to load from
7679
* @throws IllegalArgumentException if the opcode kind is not
77-
* {@link Opcode.Kind#LOAD}.
80+
* {@link Opcode.Kind#LOAD} or {@code slot} is out of range
7881
*/
7982
static LoadInstruction of(Opcode op, int slot) {
8083
Util.checkKind(op, Opcode.Kind.LOAD);
84+
BytecodeHelpers.validateSlot(op, slot, true);
8185
return new AbstractInstruction.UnboundLoadInstruction(op, slot);
8286
}
8387
}

src/java.base/share/classes/java/lang/classfile/instruction/LocalVariable.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ default ClassDesc typeSymbol() {
9292
* @param descriptorEntry the local variable descriptor
9393
* @param startScope the start range of the local variable scope
9494
* @param endScope the end range of the local variable scope
95+
* @throws IllegalArgumentException if {@code slot} is out of range
9596
*/
9697
static LocalVariable of(int slot, Utf8Entry nameEntry, Utf8Entry descriptorEntry, Label startScope, Label endScope) {
9798
return new AbstractPseudoInstruction.UnboundLocalVariable(slot, nameEntry, descriptorEntry,
@@ -106,6 +107,7 @@ static LocalVariable of(int slot, Utf8Entry nameEntry, Utf8Entry descriptorEntry
106107
* @param descriptor the local variable descriptor
107108
* @param startScope the start range of the local variable scope
108109
* @param endScope the end range of the local variable scope
110+
* @throws IllegalArgumentException if {@code slot} is out of range
109111
*/
110112
static LocalVariable of(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) {
111113
return of(slot,

src/java.base/share/classes/java/lang/classfile/instruction/LocalVariableType.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ default Signature signatureSymbol() {
8989
* @param signatureEntry the local variable signature
9090
* @param startScope the start range of the local variable scope
9191
* @param endScope the end range of the local variable scope
92+
* @throws IllegalArgumentException if {@code slot} is out of range
9293
*/
9394
static LocalVariableType of(int slot, Utf8Entry nameEntry, Utf8Entry signatureEntry, Label startScope, Label endScope) {
9495
return new AbstractPseudoInstruction.UnboundLocalVariableType(slot, nameEntry, signatureEntry,
@@ -103,6 +104,7 @@ static LocalVariableType of(int slot, Utf8Entry nameEntry, Utf8Entry signatureEn
103104
* @param signature the local variable signature
104105
* @param startScope the start range of the local variable scope
105106
* @param endScope the end range of the local variable scope
107+
* @throws IllegalArgumentException if {@code slot} is out of range
106108
*/
107109
static LocalVariableType of(int slot, String name, Signature signature, Label startScope, Label endScope) {
108110
return of(slot,

src/java.base/share/classes/java/lang/classfile/instruction/NewMultiArrayInstruction.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.lang.classfile.constantpool.ClassEntry;
3030
import java.lang.classfile.Instruction;
3131
import jdk.internal.classfile.impl.AbstractInstruction;
32+
import jdk.internal.classfile.impl.BytecodeHelpers;
3233
import jdk.internal.javac.PreviewFeature;
3334

3435
/**
@@ -58,9 +59,11 @@ public sealed interface NewMultiArrayInstruction extends Instruction
5859
*
5960
* @param arrayTypeEntry the type of the array
6061
* @param dimensions the number of dimensions of the array
62+
* @throws IllegalArgumentException if {@code dimensions} is out of range
6163
*/
6264
static NewMultiArrayInstruction of(ClassEntry arrayTypeEntry,
6365
int dimensions) {
66+
BytecodeHelpers.validateMultiArrayDimensions(dimensions);
6467
return new AbstractInstruction.UnboundNewMultidimensionalArrayInstruction(arrayTypeEntry, dimensions);
6568
}
6669
}

src/java.base/share/classes/java/lang/classfile/instruction/StoreInstruction.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,12 @@ public sealed interface StoreInstruction extends Instruction
6161
*
6262
* @param kind the type of the value to be stored
6363
* @param slot the local variable slot to store to
64+
* @throws IllegalArgumentException if {@code kind} is {@link
65+
* TypeKind#VOID void} or {@code slot} is out of range
6466
*/
6567
static StoreInstruction of(TypeKind kind, int slot) {
66-
return of(BytecodeHelpers.storeOpcode(kind, slot), slot);
68+
var opcode = BytecodeHelpers.storeOpcode(kind, slot); // validates slot
69+
return new AbstractInstruction.UnboundStoreInstruction(opcode, slot);
6770
}
6871

6972
/**
@@ -73,10 +76,11 @@ static StoreInstruction of(TypeKind kind, int slot) {
7376
* which must be of kind {@link Opcode.Kind#STORE}
7477
* @param slot the local variable slot to store to
7578
* @throws IllegalArgumentException if the opcode kind is not
76-
* {@link Opcode.Kind#STORE}.
79+
* {@link Opcode.Kind#STORE} or {@code slot} is out of range
7780
*/
7881
static StoreInstruction of(Opcode op, int slot) {
7982
Util.checkKind(op, Opcode.Kind.STORE);
83+
BytecodeHelpers.validateSlot(op, slot, false);
8084
return new AbstractInstruction.UnboundStoreInstruction(op, slot);
8185
}
8286
}

src/java.base/share/classes/jdk/internal/classfile/impl/AbstractInstruction.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,9 +848,9 @@ public static final class UnboundIncrementInstruction
848848
final int constant;
849849

850850
public UnboundIncrementInstruction(int slot, int constant) {
851-
super(slot <= 255 && constant < 128 && constant > -127
852-
? Opcode.IINC
853-
: Opcode.IINC_W);
851+
super(BytecodeHelpers.validateAndIsWideIinc(slot, constant)
852+
? Opcode.IINC_W
853+
: Opcode.IINC);
854854
this.slot = slot;
855855
this.constant = constant;
856856
}
@@ -867,7 +867,7 @@ public int constant() {
867867

868868
@Override
869869
public void writeTo(DirectCodeBuilder writer) {
870-
writer.writeIncrement(slot, constant);
870+
writer.writeIncrement(op == Opcode.IINC_W, slot, constant);
871871
}
872872

873873
@Override

src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPseudoInstruction.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ private abstract static sealed class AbstractLocalPseudo extends AbstractPseudoI
163163
protected final Label endScope;
164164

165165
public AbstractLocalPseudo(int slot, Utf8Entry name, Utf8Entry descriptor, Label startScope, Label endScope) {
166+
BytecodeHelpers.validateSlot(slot);
166167
this.slot = slot;
167168
this.name = name;
168169
this.descriptor = descriptor;

0 commit comments

Comments
 (0)