From cfb7126031c7f22de4b80e42ace30fcc32be6c78 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 16 Jul 2024 06:02:30 -0400 Subject: [PATCH] fix: respect NVD error message for resultsPerPage resolves https://github.com/jeremylong/DependencyCheck/issues/6834 --- .../client/nvd/NvdCveClient.java | 25 +++++++++++ .../client/nvd/NvdCveClientTest.java | 41 +++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 open-vulnerability-clients/src/test/java/io/github/jeremylong/openvulnerability/client/nvd/NvdCveClientTest.java diff --git a/open-vulnerability-clients/src/main/java/io/github/jeremylong/openvulnerability/client/nvd/NvdCveClient.java b/open-vulnerability-clients/src/main/java/io/github/jeremylong/openvulnerability/client/nvd/NvdCveClient.java index 9afd13bd..0d01ad30 100644 --- a/open-vulnerability-clients/src/main/java/io/github/jeremylong/openvulnerability/client/nvd/NvdCveClient.java +++ b/open-vulnerability-clients/src/main/java/io/github/jeremylong/openvulnerability/client/nvd/NvdCveClient.java @@ -391,6 +391,7 @@ private Collection _next(int retryCount) { } LOG.debug("Response: {}", new String(response.getBodyBytes(), StandardCharsets.UTF_8)); if (msg != null) { + msg = msg.trim(); if (msg.contains("Invalid apiKey")) { if (this.apiKey.length() > 30) { String masked = String.format("Invalid API Key: %s-*****-%s", @@ -400,6 +401,11 @@ private Collection _next(int retryCount) { } String masked = String.format("Invalid API Key: %s-*****", this.apiKey.substring(0, 5)); throw new NvdApiException(masked); + } else if (msg.startsWith("resultsPerPage parameter cannot exceed")) { + this.resultsPerPage = parseResultsPerPage(msg); + LOG.warn(msg); + LOG.warn("NVD requested a lower resultsPerPage; settings to {}", this.resultsPerPage); + return _next(retryCount + 1); } throw new NvdApiException("NVD Returned Status Code: " + lastStatusCode + " - " + msg); } @@ -421,6 +427,25 @@ private Collection _next(int retryCount) { return null; } + /** + * Attempts to parse the resultsPerPage error message to determine the maximum number of results per page. + * @param msg the error message from the NVD + * @return the parsed results per page if succesful; otherwise the previously confiuged results per page + */ + protected int parseResultsPerPage(String msg) { + String value = msg; + if (value.endsWith(".")) { + value = value.substring(0, value.length() - 1); + } + value = value.substring(msg.lastIndexOf(" ") + 1); + try { + return Integer.parseInt(value); + } catch (NumberFormatException e) { + LOG.debug("Error parsing " + msg, e); + } + return resultsPerPage; + } + /** * Retrieve the latest last updated date from the list of vulnerabilities. * diff --git a/open-vulnerability-clients/src/test/java/io/github/jeremylong/openvulnerability/client/nvd/NvdCveClientTest.java b/open-vulnerability-clients/src/test/java/io/github/jeremylong/openvulnerability/client/nvd/NvdCveClientTest.java new file mode 100644 index 00000000..a817f799 --- /dev/null +++ b/open-vulnerability-clients/src/test/java/io/github/jeremylong/openvulnerability/client/nvd/NvdCveClientTest.java @@ -0,0 +1,41 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * Copyright (c) 2022-2024 Jeremy Long. All Rights Reserved. + */ +package io.github.jeremylong.openvulnerability.client.nvd; + +import org.junit.jupiter.api.Assumptions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Timeout; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Collection; +import java.util.concurrent.TimeUnit; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class NvdCveClientTest { + + @Test + public void parseResultsPerPageTest() { + NvdCveClient client = new NvdCveClient(null, null, 1, 1); + client.setResultsPerPage(2000); + int recordsPerPage = client.parseResultsPerPage("resultsPerPage parameter cannot exceed 1000."); + assertEquals(1000, recordsPerPage, "Incorrect records per page value parsed"); + } +} \ No newline at end of file