Skip to content

Commit c4b12cf

Browse files
authored
Fix potential NPE for switch statement when null case is missing (#20044)
* Fix potential NPE for switch case Signed-off-by: Binlong Gao <gbinlong@amazon.com> * Remove null case if checked null before switch Signed-off-by: Binlong Gao <gbinlong@amazon.com> * Add more unit tests Signed-off-by: Binlong Gao <gbinlong@amazon.com> --------- Signed-off-by: Binlong Gao <gbinlong@amazon.com>
1 parent 6f6a545 commit c4b12cf

File tree

12 files changed

+159
-32
lines changed

12 files changed

+159
-32
lines changed

modules/lang-painless/src/main/java/org/opensearch/painless/ir/ConstantNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ protected void write(ClassWriter classWriter, MethodWriter methodWriter, WriteSc
8282
case Short shortValue -> methodWriter.push(shortValue);
8383
case Byte byteValue -> methodWriter.push(byteValue);
8484
case Boolean boolValue -> methodWriter.push(boolValue);
85-
default -> throw new IllegalStateException("unexpected constant [" + constant + "]");
85+
case null, default -> throw new IllegalStateException("unexpected constant [" + constant + "]");
8686
}
8787
}
8888
}

modules/percolator/src/main/java/org/opensearch/percolator/QueryAnalyzer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ public void visitLeaf(Query query) {
216216
case MatchAllDocsQuery ignored -> terms.add(new Result(true, true));
217217
case MatchNoDocsQuery ignored -> terms.add(Result.MATCH_NONE);
218218
case PointRangeQuery pointRangeQuery -> terms.add(pointRangeQuery(pointRangeQuery));
219-
default -> terms.add(Result.UNKNOWN);
219+
case null, default -> terms.add(Result.UNKNOWN);
220220
}
221221
}
222222

modules/transport-grpc/src/main/java/org/opensearch/transport/grpc/proto/response/exceptions/opensearchexception/OpenSearchExceptionProtoUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ public static Map<String, ObjectMap.Value> metadataToProto(OpenSearchException e
247247
case SearchParseException spe -> SearchParseExceptionProtoUtils.metadataToProto(spe);
248248
case SearchPhaseExecutionException spee -> SearchPhaseExecutionExceptionProtoUtils.metadataToProto(spee);
249249
case MultiBucketConsumerService.TooManyBucketsException tmbe -> TooManyBucketsExceptionProtoUtils.metadataToProto(tmbe);
250-
default -> new HashMap<>();
250+
case null, default -> new HashMap<>();
251251
};
252252
}
253253
}

modules/transport-grpc/src/main/java/org/opensearch/transport/grpc/proto/response/exceptions/shardoperationfailedexception/DefaultShardOperationFailedExceptionProtoUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ public static ShardFailure toProto(DefaultShardOperationFailedException exceptio
4545
indicesShardStoresFailure
4646
);
4747
case CloseIndexResponse.ShardResult.Failure closeIndexFailure -> innerToProto(shardFailureBuilder, closeIndexFailure);
48+
case null -> {
49+
}
4850
default -> parentInnerToProto(shardFailureBuilder, exception);
4951
}
5052
return shardFailureBuilder.build();

modules/transport-grpc/src/main/java/org/opensearch/transport/grpc/proto/response/exceptions/shardoperationfailedexception/ShardOperationFailedExceptionProtoUtils.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public static ShardFailure toProto(ShardOperationFailedException exception) thro
4040
case SnapshotShardFailure ssf -> SnapshotShardFailureProtoUtils.toProto(ssf);
4141
case DefaultShardOperationFailedException dsofe -> DefaultShardOperationFailedExceptionProtoUtils.toProto(dsofe);
4242
case ReplicationResponse.ShardInfo.Failure sf -> ReplicationResponseShardInfoFailureProtoUtils.toProto(sf);
43+
case null -> throw new UnsupportedOperationException(
44+
"Unsupported ShardOperationFailedException [null] cannot be converted to proto."
45+
);
4346
default -> throw new UnsupportedOperationException(
4447
"Unsupported ShardOperationFailedException " + exception.getClass().getName() + "cannot be converted to proto."
4548
);

modules/transport-grpc/src/main/java/org/opensearch/transport/grpc/util/GrpcErrorHandler.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@ public static StatusRuntimeException convertToGrpcError(Exception e) {
9797
case IOException ioException -> {
9898
return Status.INTERNAL.withDescription(ExceptionsHelper.stackTrace(ioException)).asRuntimeException();
9999
}
100-
100+
case null -> {
101+
logger.warn("Unexpected null exception type, treating as INTERNAL error");
102+
return Status.INTERNAL.withDescription("Unexpected null exception").asRuntimeException();
103+
}
101104
// ========== 5. Unknown/Unmapped Exceptions ==========
102105
// Safety fallback for any unexpected exception to {@code Status.INTERNAL} with full debugging info
103106
default -> {

modules/transport-grpc/src/test/java/org/opensearch/transport/grpc/proto/response/exceptions/shardoperationfailedexception/DefaultShardOperationFailedExceptionProtoUtilsTests.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,13 @@ public void testToProtoWithNullNodeId() throws IOException {
122122
assertFalse("Node should not be set", shardFailure.hasNode());
123123
assertNotNull("Reason should not be null", shardFailure.getReason());
124124
}
125+
126+
public void testToProtoWithNull() throws IOException {
127+
ShardFailure shardFailure = DefaultShardOperationFailedExceptionProtoUtils.toProto(null);
128+
assertNotNull("ShardFailure should not be null", shardFailure);
129+
assertFalse("Index should not be set", shardFailure.hasIndex());
130+
assertFalse("Status should not be set", shardFailure.hasStatus());
131+
assertFalse("Node should not be set", shardFailure.hasNode());
132+
assertFalse("Reason should not be set", shardFailure.hasReason());
133+
}
125134
}

modules/transport-grpc/src/test/java/org/opensearch/transport/grpc/proto/response/exceptions/shardoperationfailedexception/ShardOperationFailedExceptionProtoUtilsTests.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,14 @@ public void testToProtoWithUnsupportedShardOperationFailedException() {
119119
exception.getMessage().contains("Unsupported ShardOperationFailedException")
120120
);
121121
}
122+
123+
public void testToProtoWithNullShardOperationFailedException() {
124+
// Call the method under test with null, should throw UnsupportedOperationException
125+
UnsupportedOperationException exception = expectThrows(
126+
UnsupportedOperationException.class,
127+
() -> ShardOperationFailedExceptionProtoUtils.toProto(null)
128+
);
129+
130+
assertEquals("Unsupported ShardOperationFailedException [null] cannot be converted to proto.", exception.getMessage());
131+
}
122132
}

modules/transport-grpc/src/test/java/org/opensearch/transport/grpc/util/GrpcErrorHandlerTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,4 +279,12 @@ public RestStatus status() {
279279
assertTrue(result.getMessage().contains("Root cause"));
280280
assertTrue(result.getMessage().contains("Wrapper exception"));
281281
}
282+
283+
public void testNullExceptionConversion() {
284+
StatusRuntimeException result = GrpcErrorHandler.convertToGrpcError(null);
285+
286+
// null -> INTERNAL via case null handling
287+
assertEquals(Status.INTERNAL.getCode(), result.getStatus().getCode());
288+
assertEquals("INTERNAL: Unexpected null exception", result.getMessage());
289+
}
282290
}

server/src/main/java/org/opensearch/common/inject/internal/Errors.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ public static Collection<Message> getMessagesFromThrowable(Throwable throwable)
356356
case ProvisionException provisionException -> provisionException.getErrorMessages();
357357
case ConfigurationException configurationException -> configurationException.getErrorMessages();
358358
case CreationException creationException -> creationException.getErrorMessages();
359-
default -> emptySet();
359+
case null, default -> emptySet();
360360
};
361361
}
362362

0 commit comments

Comments
 (0)