From f9a5196342035aa07a2a3d785420ff88c1587133 Mon Sep 17 00:00:00 2001 From: nscuro Date: Fri, 29 Nov 2024 15:55:57 +0100 Subject: [PATCH] Fix broken pagination in `/api/v1/cwe` endpoint Fixes #3856 Signed-off-by: nscuro --- .../parser/common/resolver/CweResolver.java | 21 +++++++------ .../resources/v1/CweResourceTest.java | 30 +++++++++++++++++++ 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/dependencytrack/parser/common/resolver/CweResolver.java b/src/main/java/org/dependencytrack/parser/common/resolver/CweResolver.java index 0659e187b7..84770782f7 100644 --- a/src/main/java/org/dependencytrack/parser/common/resolver/CweResolver.java +++ b/src/main/java/org/dependencytrack/parser/common/resolver/CweResolver.java @@ -129,22 +129,21 @@ public PaginatedResult all(final Pagination pagination) { return new PaginatedResult().objects(cwes).total(CweDictionary.DICTIONARY.size()); } - int pos = 0; + int pos = 0, count = 0; final var cwes = new ArrayList(); for (final Map.Entry dictEntry : CweDictionary.DICTIONARY.entrySet()) { - if (pagination.getOffset() > pos) { - continue; + if (pos >= pagination.getOffset() && count < pagination.getLimit()) { + final var cwe = new Cwe(); + cwe.setCweId(dictEntry.getKey()); + cwe.setName(dictEntry.getValue()); + cwes.add(cwe); + count++; } - if (pagination.getLimit() <= pos) { - break; - } - - final var cwe = new Cwe(); - cwe.setCweId(dictEntry.getKey()); - cwe.setName(dictEntry.getValue()); - cwes.add(cwe); pos++; + if (count >= pagination.getLimit()) { + break; + } } return new PaginatedResult().objects(cwes).total(CweDictionary.DICTIONARY.size()); diff --git a/src/test/java/org/dependencytrack/resources/v1/CweResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/CweResourceTest.java index 1ab122387c..083cb0c614 100644 --- a/src/test/java/org/dependencytrack/resources/v1/CweResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/CweResourceTest.java @@ -22,6 +22,7 @@ import alpine.server.filters.AuthenticationFilter; import org.dependencytrack.JerseyTestRule; import org.dependencytrack.ResourceTest; +import org.dependencytrack.parser.common.resolver.CweDictionary; import org.glassfish.jersey.server.ResourceConfig; import org.junit.Assert; import org.junit.ClassRule; @@ -30,6 +31,9 @@ import jakarta.json.JsonArray; import jakarta.json.JsonObject; import jakarta.ws.rs.core.Response; +import java.util.HashSet; + +import static org.assertj.core.api.Assertions.assertThat; public class CweResourceTest extends ResourceTest { @@ -53,6 +57,31 @@ public void getCwesTest() { Assert.assertEquals("DEPRECATED: Location", json.getJsonObject(0).getString("name")); } + @Test + public void getCwesPaginationTest() { + int pageNumber = 1; + final var cwesSeen = new HashSet(); + while (cwesSeen.size() < CweDictionary.DICTIONARY.size()) { + final Response response = jersey.target(V1_CWE) + .queryParam("pageSize", "100") + .queryParam("pageNumber", String.valueOf(pageNumber++)) + .request() + .header(X_API_KEY, apiKey) + .get(); + assertThat(response.getStatus()).isEqualTo(200); + assertThat(response.getHeaderString(TOTAL_COUNT_HEADER)).isEqualTo("1426"); + + final JsonArray cwesPage = parseJsonArray(response); + assertThat(cwesPage).hasSizeLessThanOrEqualTo(100); + + for (final JsonObject value : cwesPage.getValuesAs(JsonObject.class)) { + final int cweId = value.getInt("cweId"); + assertThat(cwesSeen).doesNotContain(cweId); + cwesSeen.add(cweId); + } + } + } + @Test public void getCweTest() { Response response = jersey.target(V1_CWE + "/79").request() @@ -65,4 +94,5 @@ public void getCweTest() { Assert.assertEquals(79, json.getInt("cweId")); Assert.assertEquals("Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')", json.getString("name")); } + }