@@ -1125,7 +1125,8 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
1125
1125
}
1126
1126
1127
1127
MethodRef method = verifyMethodRef (input .readLong (), reply , context );
1128
- if (method == null ) {
1128
+ if (method == null || !Modifier .isStatic (method .getModifiers ()) || method .isClassInitializer ()) {
1129
+ reply .errorCode (ErrorCodes .INVALID_METHODID );
1129
1130
return new CommandResult (reply );
1130
1131
}
1131
1132
@@ -1160,12 +1161,7 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
1160
1161
try {
1161
1162
// we have to call the method in the correct thread, so post a
1162
1163
// Callable to the controller and wait for the result to appear
1163
- ThreadJob <Object > job = new ThreadJob <>(thread , new Callable <>() {
1164
- @ Override
1165
- public Object call () {
1166
- return method .invokeMethod (null , args );
1167
- }
1168
- }, suspensionStrategy );
1164
+ ThreadJob <Object > job = new ThreadJob <>(thread , () -> method .invokeMethodStatic (args ), suspensionStrategy );
1169
1165
controller .postJobForThread (job );
1170
1166
1171
1167
// invocation of a method can cause events with possible thread suspension
@@ -1209,6 +1205,10 @@ static CommandResult createReply(Packet packet, DebuggerController controller) {
1209
1205
if (klass == null ) {
1210
1206
return new CommandResult (reply );
1211
1207
}
1208
+ if (klass .isArray () || klass .isInterface () || Modifier .isAbstract (klass .getModifiers ())) {
1209
+ reply .errorCode (ErrorCodes .INVALID_CLASS );
1210
+ return new CommandResult (reply );
1211
+ }
1212
1212
1213
1213
Object thread = verifyThread (input .readLong (), reply , context , true );
1214
1214
if (thread == null ) {
@@ -1223,32 +1223,31 @@ static CommandResult createReply(Packet packet, DebuggerController controller) {
1223
1223
}
1224
1224
1225
1225
MethodRef method = verifyMethodRef (input .readLong (), reply , context );
1226
- if (method == null ) {
1227
- controller . warning (() -> "not a valid method" );
1226
+ if (method == null || ! method . isConstructor () || method . getDeclaringKlassRef () != klass ) {
1227
+ reply . errorCode ( ErrorCodes . INVALID_METHODID );
1228
1228
return new CommandResult (reply );
1229
1229
}
1230
1230
1231
1231
controller .fine (() -> "trying to invoke constructor in klass: " + klass .getNameAsString ());
1232
1232
1233
1233
int arguments = input .readInt ();
1234
1234
1235
- Object [] args = new Object [arguments ];
1236
- for (int i = 0 ; i < arguments ; i ++) {
1235
+ Object [] args = new Object [arguments + 1 ];
1236
+ // we leave room for the allocated object as the first arg
1237
+ for (int i = 1 ; i < args .length ; i ++) {
1237
1238
byte valueKind = input .readByte ();
1238
1239
args [i ] = readValue (valueKind , input , context );
1239
1240
}
1240
1241
1241
1242
int invocationOptions = input .readInt ();
1242
1243
byte suspensionStrategy = invocationOptions == 1 ? SuspendStrategy .EVENT_THREAD : SuspendStrategy .ALL ;
1243
1244
try {
1244
- // we have to call the method in the correct thread, so post a
1245
+ // we have to call the constructor in the correct thread, so post a
1245
1246
// Callable to the controller and wait for the result to appear
1246
- ThreadJob <?> job = new ThreadJob <>(thread , new Callable <>() {
1247
-
1248
- @ Override
1249
- public Object call () throws Exception {
1250
- return method .invokeMethod (null , args );
1251
- }
1247
+ ThreadJob <?> job = new ThreadJob <>(thread , () -> {
1248
+ args [0 ] = context .allocateInstance (klass );
1249
+ method .invokeMethodSpecial (args );
1250
+ return args [0 ];
1252
1251
}, suspensionStrategy );
1253
1252
controller .postJobForThread (job );
1254
1253
ThreadJob <?>.JobResult <?> result = job .getResult ();
@@ -1329,7 +1328,7 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
1329
1328
return new CommandResult (reply );
1330
1329
}
1331
1330
1332
- if (method .getDeclaringKlassRef () != itf ) {
1331
+ if (method .getDeclaringKlassRef () != itf || ! Modifier . isStatic ( method . getModifiers ()) || method . isClassInitializer () ) {
1333
1332
reply .errorCode (ErrorCodes .INVALID_METHODID );
1334
1333
return new CommandResult (reply );
1335
1334
}
@@ -1349,13 +1348,7 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
1349
1348
try {
1350
1349
// we have to call the method in the correct thread, so post a
1351
1350
// Callable to the controller and wait for the result to appear
1352
- ThreadJob <Object > job = new ThreadJob <>(thread , new Callable <>() {
1353
-
1354
- @ Override
1355
- public Object call () throws Exception {
1356
- return method .invokeMethod (null , args );
1357
- }
1358
- }, suspensionStrategy );
1351
+ ThreadJob <Object > job = new ThreadJob <>(thread , () -> method .invokeMethodStatic (args ), suspensionStrategy );
1359
1352
controller .postJobForThread (job );
1360
1353
// invocation of a method can cause events with possible thread suspension
1361
1354
// to happen, e.g. class prepare events for newly loaded classes
@@ -1755,6 +1748,14 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
1755
1748
JDWPContext context = controller .getContext ();
1756
1749
1757
1750
long objectId = input .readLong ();
1751
+
1752
+ Object receiver = context .getIds ().fromId ((int ) objectId );
1753
+ if (receiver == null ) {
1754
+ // object was garbage collected
1755
+ reply .errorCode (ErrorCodes .INVALID_OBJECT );
1756
+ return new CommandResult (reply );
1757
+ }
1758
+
1758
1759
long threadId = input .readLong ();
1759
1760
1760
1761
Object thread = verifyThread (threadId , reply , context , true );
@@ -1775,42 +1776,38 @@ static CommandResult createReply(Packet packet, DebuggerController controller, D
1775
1776
}
1776
1777
1777
1778
long methodId = input .readLong ();
1778
- int arguments = input .readInt ();
1779
-
1780
- Object [] args = new Object [arguments ];
1781
- for (int i = 0 ; i < arguments ; i ++) {
1782
- byte valueKind = input .readByte ();
1783
- args [i ] = readValue (valueKind , input , context );
1784
- }
1785
-
1786
- Object callee = context .getIds ().fromId ((int ) objectId );
1787
- if (callee == null ) {
1788
- // object was garbage collected
1789
- reply .errorCode (ErrorCodes .INVALID_OBJECT );
1790
- return new CommandResult (reply );
1791
- }
1792
1779
MethodRef method = verifyMethodRef (methodId , reply , context );
1793
1780
1794
1781
if (method == null ) {
1795
1782
return new CommandResult (reply );
1796
1783
}
1797
1784
1798
- if (!context .isMemberOf (callee , method .getDeclaringKlassRef ())) {
1785
+ if (Modifier . isStatic ( method . getModifiers ()) || method . isConstructor () || !context .isMemberOf (receiver , method .getDeclaringKlassRef ())) {
1799
1786
reply .errorCode (ErrorCodes .INVALID_METHODID );
1800
1787
return new CommandResult (reply );
1801
1788
}
1802
1789
1790
+ int arguments = input .readInt ();
1791
+
1792
+ Object [] args = new Object [arguments + 1 ];
1793
+ args [0 ] = receiver ;
1794
+ for (int i = 1 ; i < args .length ; i ++) {
1795
+ byte valueKind = input .readByte ();
1796
+ args [i ] = readValue (valueKind , input , context );
1797
+ }
1798
+
1803
1799
controller .fine (() -> "trying to invoke method: " + method .getNameAsString ());
1804
1800
1805
1801
int invocationOptions = input .readInt ();
1806
1802
byte suspensionStrategy = invocationOptions == 1 ? SuspendStrategy .EVENT_THREAD : SuspendStrategy .ALL ;
1807
1803
try {
1808
1804
// we have to call the method in the correct thread, so post a
1809
1805
// Callable to the controller and wait for the result to appear
1810
- ThreadJob <Object > job = new ThreadJob <>(thread , new Callable <>() {
1811
- @ Override
1812
- public Object call () throws Exception {
1813
- return method .invokeMethod (callee , args );
1806
+ ThreadJob <Object > job = new ThreadJob <>(thread , () -> {
1807
+ if (Modifier .isPrivate (method .getModifiers ())) {
1808
+ return method .invokeMethodSpecial (args );
1809
+ } else {
1810
+ return method .invokeMethodVirtual (args );
1814
1811
}
1815
1812
}, suspensionStrategy );
1816
1813
controller .postJobForThread (job );
@@ -2539,7 +2536,7 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
2539
2536
return new CommandResult (reply );
2540
2537
}
2541
2538
2542
- byte tag = context .getTypeTag (array );
2539
+ byte tag = context .getArrayComponentTag (array );
2543
2540
boolean isPrimitive = TagConstants .isPrimitive (tag );
2544
2541
2545
2542
reply .writeByte (tag );
@@ -2570,64 +2567,28 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
2570
2567
return new CommandResult (reply );
2571
2568
}
2572
2569
2573
- byte tag = context .getTypeTag (array );
2570
+ byte tag = context .getArrayComponentTag (array );
2574
2571
2575
2572
setArrayValues (context , input , index , values , array , tag );
2576
2573
return new CommandResult (reply );
2577
2574
}
2578
2575
2579
2576
private static void setArrayValues (JDWPContext context , PacketStream input , int index , int values , Object array , byte tag ) {
2580
2577
for (int i = index ; i < index + values ; i ++) {
2581
- switch (tag ) {
2582
- case TagConstants .BOOLEAN :
2583
- boolean bool = input .readBoolean ();
2584
- byte [] boolArray = context .getUnboxedArray (array );
2585
- boolArray [i ] = bool ? (byte ) 1 : (byte ) 0 ;
2586
- break ;
2587
- case TagConstants .BYTE :
2588
- byte b = input .readByte ();
2589
- byte [] byteArray = context .getUnboxedArray (array );
2590
- byteArray [i ] = b ;
2591
- break ;
2592
- case TagConstants .SHORT :
2593
- short s = input .readShort ();
2594
- short [] shortArray = context .getUnboxedArray (array );
2595
- shortArray [i ] = s ;
2596
- break ;
2597
- case TagConstants .CHAR :
2598
- char c = input .readChar ();
2599
- char [] charArray = context .getUnboxedArray (array );
2600
- charArray [i ] = c ;
2601
- break ;
2602
- case TagConstants .INT :
2603
- int j = input .readInt ();
2604
- int [] intArray = context .getUnboxedArray (array );
2605
- intArray [i ] = j ;
2606
- break ;
2607
- case TagConstants .FLOAT :
2608
- float f = input .readFloat ();
2609
- float [] floatArray = context .getUnboxedArray (array );
2610
- floatArray [i ] = f ;
2611
- break ;
2612
- case TagConstants .LONG :
2613
- long l = input .readLong ();
2614
- long [] longArray = context .getUnboxedArray (array );
2615
- longArray [i ] = l ;
2616
- break ;
2617
- case TagConstants .DOUBLE :
2618
- double d = input .readDouble ();
2619
- double [] doubleArray = context .getUnboxedArray (array );
2620
- doubleArray [i ] = d ;
2621
- break ;
2622
- case TagConstants .ARRAY :
2623
- case TagConstants .STRING :
2624
- case TagConstants .OBJECT :
2625
- Object value = context .getIds ().fromId ((int ) input .readLong ());
2626
- context .setArrayValue (array , i , value );
2627
- break ;
2628
- default :
2629
- throw new RuntimeException ("should not reach here" );
2630
- }
2578
+ Object value = switch (tag ) {
2579
+ case TagConstants .BOOLEAN -> input .readBoolean ();
2580
+ case TagConstants .BYTE -> input .readByte ();
2581
+ case TagConstants .SHORT -> input .readShort ();
2582
+ case TagConstants .CHAR -> input .readChar ();
2583
+ case TagConstants .INT -> input .readInt ();
2584
+ case TagConstants .FLOAT -> input .readFloat ();
2585
+ case TagConstants .LONG -> input .readLong ();
2586
+ case TagConstants .DOUBLE -> input .readDouble ();
2587
+ case TagConstants .ARRAY , TagConstants .STRING , TagConstants .OBJECT ->
2588
+ context .getIds ().fromId ((int ) input .readLong ());
2589
+ default -> throw new RuntimeException ("should not reach here: " + tag );
2590
+ };
2591
+ context .setArrayValue (array , i , value );
2631
2592
}
2632
2593
}
2633
2594
}
@@ -3084,7 +3045,7 @@ private static void writeMethodResult(PacketStream reply, JDWPContext context, T
3084
3045
controller .getGCPrevention ().setActiveWhileSuspended (thread , guestException );
3085
3046
}
3086
3047
} else {
3087
- Object value = context . toGuest ( result .getResult () );
3048
+ Object value = result .getResult ();
3088
3049
if (value != null ) {
3089
3050
byte tag = context .getTag (value );
3090
3051
writeValue (tag , value , reply , true , context );
0 commit comments