Skip to content

fix: sort CVE records correctly#2020

Merged
ctron merged 1 commit intoguacsec:mainfrom
lcarva:fix-cve-ordering
Mar 5, 2026
Merged

fix: sort CVE records correctly#2020
ctron merged 1 commit intoguacsec:mainfrom
lcarva:fix-cve-ordering

Conversation

@lcarva
Copy link
Copy Markdown
Contributor

@lcarva lcarva commented Oct 8, 2025

CVE records follow a specific format where the last segment represents a numerical sequence. To properly sort CVE records, we must treat this sequence segment differently than the rest of the record ID.

fixes #1811

Summary by Sourcery

Implement proper numeric sorting for CVE identifiers by introducing a normalized sort key and updating the sorting translator to use it, ensuring correct ascending and descending order across different ID prefixes.

Enhancements:

  • Introduce id_sort_key SQL expression to pad the numeric segment of CVE IDs for accurate numeric sorting.
  • Translate id sort operations to use the new id_sort_key when sorting vulnerabilities.

Tests:

  • Add vulnerability_numeric_sorting integration test to verify correct ascending and descending ordering for CVE, GHSA, and custom IDs.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented Oct 8, 2025

Reviewer's Guide

Implement numeric-aware sorting for CVE identifiers by introducing a normalized SQL sort key (id_sort_key) and updating the sort translator to route 'id' sorts through it, and add tests to verify correct ascending and descending ordering.

Entity relationship diagram for CVE ID sorting key

erDiagram
    VULNERABILITY {
        id TEXT
        id_sort_key TEXT
    }
    VULNERABILITY ||--o{ PAGINATED_RESULTS : contains
    VULNERABILITY ||--o{ COLUMNS : uses
    COLUMNS {
        id_sort_key TEXT
    }
Loading

File-Level Changes

Change Details Files
Introduce id_sort_key expression and translate 'id' sorts to numeric-aware key
  • Add a CASE expression (id_sort_key) that pads the trailing CVE sequence to 19 digits
  • Extend filtering_with translator to map sort('id') to id_sort_key:asc/desc
  • Retain alphabetical sorting for non-CVE prefixes by falling back to raw id
modules/fundamental/src/vulnerability/service/mod.rs
Add vulnerability_numeric_sorting test for mixed identifier ordering
  • Ingest a set of CVE, GHSA and ABC identifiers with varying numeric lengths
  • Verify ascending id sort returns ABC < CVE-2023-1234 < ... < GHSA
  • Verify descending id sort correctly reverses that order
modules/fundamental/src/vulnerability/service/test.rs

Assessment against linked issues

Issue Objective Addressed Explanation
#1811 Ensure that GET /api/v2/vulnerability?sort=id:desc returns vulnerabilities sorted by identifier such that CVE records are ordered numerically by their trailing sequence number, not lexicographically.
#1811 Add or update tests to verify correct numeric sorting of vulnerability identifiers, including CVE records and other formats.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown
Contributor

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • Extract the CASE WHEN regex padding logic into a named constant or helper to improve readability and avoid inline SQL clutter.
  • Consider persisting the computed id_sort_key as a computed (or materialized) column and indexing it to avoid expensive regex/substring processing on each query.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Extract the CASE WHEN regex padding logic into a named constant or helper to improve readability and avoid inline SQL clutter.
- Consider persisting the computed id_sort_key as a computed (or materialized) column and indexing it to avoid expensive regex/substring processing on each query.

## Individual Comments

### Comment 1
<location> `modules/fundamental/src/vulnerability/service/test.rs:545-540` </location>
<code_context>
+async fn vulnerability_numeric_sorting(ctx: &TrustifyContext) -> Result<(), anyhow::Error> {
</code_context>

<issue_to_address>
**suggestion (testing):** Consider adding tests for edge cases such as malformed or non-standard CVE IDs.

Including malformed CVE IDs in tests will help verify that the sort key logic handles unexpected formats correctly.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread modules/fundamental/src/vulnerability/service/test.rs
@ctron
Copy link
Copy Markdown
Contributor

ctron commented Oct 9, 2025

The change looks good. I'm just not sure it is the right approach.

Yes, it makes it more convenient for CVE IDs. However, there are a lot of OSV sources which use a similar format:

Now the user would see CVE IDs sorted differently than those. And that would be hard to explain and understand.

If we can change this to a way that we split this into components and then sort each part as ASCII or numeric (if it's numeric only), I think this could work.

@lcarva
Copy link
Copy Markdown
Contributor Author

lcarva commented Oct 9, 2025

The change looks good. I'm just not sure it is the right approach.

Yes, it makes it more convenient for CVE IDs. However, there are a lot of OSV sources which use a similar format:

Thank you. I wasn't aware of those. I think we could certainly generalize those patterns.

Out of those three examples, MAL and PSF do seem to follow the same pattern as CVE. RUSTSEC, if I'm reading the spec correctly, always requires 4 digits in the sequence sections, thus 0072 in the example above. Not sure what happens when there are more than 9,999 RUSTSEC records in a single year.

For my own notes, the different sources are listed here. Interestingly, some sources follow a slightly different pattern: https://github.com/AlmaLinux/osv-database/tree/master/advisories/almalinux10

Let me explore a way to generalize this.

Do you have any performance concerns with this approach? We could introduce a new column that stores the computed sort ID but maybe that's a premature performance improvement right now.

@ctron
Copy link
Copy Markdown
Contributor

ctron commented Oct 10, 2025

Do you have any performance concerns with this approach? We could introduce a new column that stores the computed sort ID but maybe that's a premature performance improvement right now.

I always have concerns. 😬 And especially for performance. But we do have scale tests, which can be triggered using /scale-test on a PR. Assuming we capture this use case with them (maybe we need to extend) we should be sure enough that we don't impact performance. Or we understand what the impact is and can make a decision.

Comment thread modules/fundamental/src/vulnerability/service/mod.rs Outdated
@lcarva
Copy link
Copy Markdown
Contributor Author

lcarva commented Oct 17, 2025

Pushed a change to make the sorting handle different vulnerability IDs. It looks like I broke some tests, I'll have a look at those next, but wanted to share the hmm... creative solution.

@lcarva
Copy link
Copy Markdown
Contributor Author

lcarva commented Oct 31, 2025

Pushed a change to make the sorting handle different vulnerability IDs. It looks like I broke some tests, I'll have a look at those next, but wanted to share the hmm... creative solution.

The tests were broken. I just didn't have the expected locale set on my local system. LC_ALL=C cargo test does the job. I expect it will pass here as well.

If we want the approach of using expressions at query time, I believe the changes here achieve that. It would be great for someone with access to approve running the workflows and maybe run /scale-test.

@PhilipCattanach
Copy link
Copy Markdown

@Strum355 @ctron
Gents, this PR has been open for 93 days.
Can we bring it to a successful conclusion please?

@ctron
Copy link
Copy Markdown
Contributor

ctron commented Feb 9, 2026

@Strum355 @ctron Gents, this PR has been open for 93 days. Can we bring it to a successful conclusion please?

I think the concern mentioned in #2020 (comment) is valid and should be addressed. We also do need some performance tests.

@PhilipCattanach
Copy link
Copy Markdown

This is a change that I think will be very beneficial to RHTPA. But I think we need to revisit the mechanics of the solution to ensure it is performant and develop some scale tests for it. So I've created this ticket TC-3602 to bring this work to a successful conclusion.

@PhilipCattanach
Copy link
Copy Markdown

@lcarva - Luiz do you think you'll be able to find some time to address the PR feedback?

@lcarva
Copy link
Copy Markdown
Contributor Author

lcarva commented Feb 18, 2026

Changes have been pushed to address the feedback and are now ready for review 🙏

Copy link
Copy Markdown
Contributor

@ctron ctron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for following up! Graphql was removed, maybe the PR needs to be rebased. However, I suspect a rebase conflict with the migration once the group PR is (finally) merged. So maybe wait until that.

I like the idea of that materialized column. That might increase storage, but should sort the performance issue.

I guess the test could benefit a bit from DRY-ing it up.

Comment thread entity/src/vulnerability.rs Outdated
Comment thread migration/src/m0002050_vulnerability_id_sort_index.rs Outdated
Comment thread migration/src/m0002050_vulnerability_id_sort_index.rs Outdated
Comment thread modules/fundamental/src/vulnerability/service/test.rs
Comment thread modules/fundamental/src/vulnerability/service/test.rs
Comment thread modules/fundamental/src/vulnerability/service/test.rs Outdated
@lcarva
Copy link
Copy Markdown
Contributor Author

lcarva commented Feb 19, 2026

@ctron, I believe I addressed all the comments.

@ctron
Copy link
Copy Markdown
Contributor

ctron commented Mar 4, 2026

/scale-test

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 4, 2026

🛠️ Scale test has started! Follow the progress here: Workflow Run

Copy link
Copy Markdown
Contributor

@ctron ctron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Let's not forget to check scale tests before merging.

@ctron
Copy link
Copy Markdown
Contributor

ctron commented Mar 4, 2026

Looks like it needs to be re-based and have cargo fmt run (or cargo xtask precommit)

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 4, 2026

Goose Report

Goose Attack Report

Plan Overview

Action Started Stopped Elapsed Users
Increasing 26-03-04 15:46:07 26-03-04 15:46:14 00:00:07 0 → 7
Maintaining 26-03-04 15:46:14 26-03-04 15:51:14 00:05:00 7
Decreasing 26-03-04 15:51:14 26-03-04 15:52:00 00:00:46 0 ← 7

Request Metrics

Method Name # Requests # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
DELETE delete_sbom_from_pool_sequential[100 SBOMs] 1 (0) 1 300000.00 (+0.00) 300000 (0) 300000 (0) 0.00 (+0.00) 0.00 (+0.00)
GET get_analysis_latest_cpe 5 (0) 0 16.40 (+6.40) 11 (+2) 22 (+11) 0.02 (+0.00) 0.00 (+0.00)
GET get_analysis_status 5 (0) 0 18.60 (+13.20) 3 (-2) 73 (+67) 0.02 (+0.00) 0.00 (+0.00)
GET get_sbom[sha256:a3442b37…3040057f79c70669] 5 (0) 0 1359.80 (-2973.20) 508 (-705) 3296 (-8587) 0.02 (+0.00) 0.00 (+0.00)
GET get_sbom_advisories[sha256:a3442b37…3040057f79c70669] 5 (0) 0 267208.59 (+19772.00) 252977 (+15713) 271312 (+16820) 0.02 (+0.00) 0.00 (+0.00)
GET list_advisory_labels 5 (0) 0 14475.00 (-3931.60) 8688 (-6137) 16783 (-11243) 0.02 (+0.00) 0.00 (+0.00)
GET list_importer 1 0 2.00 2 2 0.00 0.00
GET list_packages 1 0 280.00 280 280 0.00 0.00
GET list_packages_paginated 1 0 200.00 200 200 0.00 0.00
GET list_products 5 (0) 0 19.80 (+8.80) 12 (+2) 24 (+12) 0.02 (+0.00) 0.00 (+0.00)
GET list_sboms 5 (0) 0 35999.60 (+6306.40) 33520 (+3831) 45902 (+16203) 0.02 (+0.00) 0.00 (+0.00)
GET list_sboms_paginated 5 (0) 0 954.60 (+488.00) 711 (+250) 1899 (+1429) 0.02 (+0.00) 0.00 (+0.00)
GET list_vulnerabilities 1 0 273.00 273 273 0.00 0.00
GET list_vulnerabilities_paginated 1 0 119.00 119 119 0.00 0.00
GET search_exact_purl 5 (0) 0 230.00 (+61.00) 158 (-10) 475 (+305) 0.02 (+0.00) 0.00 (+0.00)
GET search_licenses 12 (+11) 0 115.67 (-205.33) 6 (-315) 641 (+320) 0.04 (+0.04) 0.00 (+0.00)
GET search_purls 5 (0) 0 26838.80 (+7152.80) 24264 (+8106) 32142 (+10618) 0.02 (+0.00) 0.00 (+0.00)
GET search_purls_by_license 13 (+11) 0 23086.54 (-144482.97) 6278 (-28860) 79525 (-220476) 0.04 (+0.04) 0.00 (-0.00)
GET search_sboms_by_license 12 (+11) 0 49.08 (-52.92) 8 (-94) 171 (+69) 0.04 (+0.04) 0.00 (+0.00)
Aggregated 93 (+38) 1 25146.04 (-15520.30) 2 (-3) 300000 (-1) 0.31 (+0.13) 0.00 (-0.00)

Response Time Metrics

Method Name 50%ile (ms) 60%ile (ms) 70%ile (ms) 80%ile (ms) 90%ile (ms) 95%ile (ms) 99%ile (ms) 100%ile (ms)
DELETE delete_sbom_from_pool_sequential[100 SBOMs] 300,000 (0) 300,000 (0) 300,000 (0) 300,000 (0) 300,000 (0) 300,000 (0) 300,000 (0) 300,000 (0)
GET get_analysis_latest_cpe 17 (+7) 17 (+7) 17 (+7) 17 (+7) 22 (+11) 22 (+11) 22 (+11) 22 (+11)
GET get_analysis_status 5 (0) 5 (0) 7 (+1) 7 (+1) 73 (+67) 73 (+67) 73 (+67) 73 (+67)
GET get_sbom[sha256:a3442b37…3040057f79c70669] 1,000 (-1,000) 1,000 (-1,000) 1,000 (-4,000) 1,000 (-4,000) 3,000 (-8,883) 3,000 (-8,883) 3,000 (-8,883) 3,000 (-8,883)
GET get_sbom_advisories[sha256:a3442b37…3040057f79c70669] 271,000 (+23,000) 271,000 (+23,000) 271,000 (+19,000) 271,000 (+19,000) 271,000 (+17,000) 271,000 (+17,000) 271,000 (+17,000) 271,000 (+17,000)
GET list_advisory_labels 16,000 (0) 16,000 (0) 16,000 (-2,000) 16,000 (-2,000) 16,783 (-11,217) 16,783 (-11,217) 16,783 (-11,217) 16,783 (-11,217)
GET list_importer 2 2 2 2 2 2 2 2
GET list_packages 280 280 280 280 280 280 280 280
GET list_packages_paginated 200 200 200 200 200 200 200 200
GET list_products 21 (+10) 21 (+10) 21 (+10) 21 (+10) 24 (+12) 24 (+12) 24 (+12) 24 (+12)
GET list_sboms 34,000 (+4,301) 34,000 (+4,301) 34,000 (+4,301) 34,000 (+4,301) 45,902 (+16,203) 45,902 (+16,203) 45,902 (+16,203) 45,902 (+16,203)
GET list_sboms_paginated 711 (+241) 711 (+241) 711 (+241) 711 (+241) 1,899 (+1,429) 1,899 (+1,429) 1,899 (+1,429) 1,899 (+1,429)
GET list_vulnerabilities 273 273 273 273 273 273 273 273
GET list_vulnerabilities_paginated 119 119 119 119 119 119 119 119
GET search_exact_purl 180 (+10) 180 (+10) 180 (+10) 180 (+10) 475 (+305) 475 (+305) 475 (+305) 475 (+305)
GET search_licenses 78 (-243) 78 (-243) 84 (-237) 110 (-211) 160 (-161) 160 (-161) 600 (+279) 600 (+279)
GET search_purls 26,000 (+6,000) 26,000 (+6,000) 26,000 (+5,000) 26,000 (+5,000) 32,000 (+10,476) 32,000 (+10,476) 32,000 (+10,476) 32,000 (+10,476)
GET search_purls_by_license 24,000 (-11,138) 24,000 (-11,138) 25,000 (-10,138) 25,000 (-275,000) 26,000 (-274,000) 26,000 (-274,000) 79,525 (-220,475) 79,525 (-220,475)
GET search_sboms_by_license 18 (-84) 22 (-80) 36 (-66) 86 (-16) 110 (+8) 110 (+8) 170 (+68) 170 (+68)
Aggregated 280 (-720) 1,000 (-14,000) 15,000 (-5,000) 25,000 (-5,000) 34,000 (-211,000) 253,000 (+1,000) 271,000 (-29,000) 300,000 (0)

Status Code Metrics

Method Name Status Codes
DELETE delete_sbom_from_pool_sequential[100 SBOMs] 1 [0]
GET get_analysis_latest_cpe 5 [200]
GET get_analysis_status 5 [200]
GET get_sbom[sha256:a3442b37…3040057f79c70669] 5 [200]
GET get_sbom_advisories[sha256:a3442b37…3040057f79c70669] 5 [200]
GET list_advisory_labels 5 [200]
GET list_importer 1 [200]
GET list_packages 1 [200]
GET list_packages_paginated 1 [200]
GET list_products 5 [200]
GET list_sboms 5 [200]
GET list_sboms_paginated 5 [200]
GET list_vulnerabilities 1 [200]
GET list_vulnerabilities_paginated 1 [200]
GET search_exact_purl 5 [200]
GET search_licenses 12 [200]
GET search_purls 5 [200]
GET search_purls_by_license 13 [200]
GET search_sboms_by_license 12 [200]
Aggregated 92 [200], 1 [0]

Transaction Metrics

Transaction # Times Run # Fails Average (ms) Min (ms) Max (ms) RPS Failures/s
WebsiteUser
0.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.1 website_index 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.2 website_openapi 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.3 website_sboms 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.4 website_packages 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.5 website_advisories 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
0.6 website_importers 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUser
1.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.1 list_organizations 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.2 list_advisory 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.3 list_advisory_paginated 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.4 get_advisory_by_doc_id 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.5 search_advisory 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.6 list_vulnerabilities 1 (+1) 0 (0) 273.00 (+273.00) 273 (+273) 273 (+273) 0.00 (+0.00) 0.00 (+0.00)
1.7 list_vulnerabilities_paginated 1 (+1) 0 (0) 119.00 (+119.00) 119 (+119) 119 (+119) 0.00 (+0.00) 0.00 (+0.00)
1.8 list_importer 1 (+1) 0 (0) 2.00 (+2.00) 2 (+2) 2 (+2) 0.00 (+0.00) 0.00 (+0.00)
1.9 list_packages 1 (+1) 0 (0) 280.00 (+280.00) 280 (+280) 280 (+280) 0.00 (+0.00) 0.00 (+0.00)
1.10 list_packages_paginated 1 (+1) 0 (0) 200.00 (+200.00) 200 (+200) 200 (+200) 0.00 (+0.00) 0.00 (+0.00)
1.11 search_purls 5 (0) 0 (0) 26838.80 (+7152.60) 24264 (+8106) 32142 (+10618) 0.02 (+0.00) 0.00 (+0.00)
1.12 search_exact_purl 5 (0) 0 (0) 230.20 (+61.20) 158 (-10) 475 (+305) 0.02 (+0.00) 0.00 (+0.00)
1.13 list_products 5 (0) 0 (0) 19.80 (+8.80) 12 (+2) 24 (+12) 0.02 (+0.00) 0.00 (+0.00)
1.14 list_sboms 5 (0) 0 (0) 35999.60 (+6306.40) 33520 (+3831) 45902 (+16203) 0.02 (+0.00) 0.00 (+0.00)
1.15 list_sboms_paginated 5 (0) 0 (0) 954.80 (+488.20) 712 (+251) 1899 (+1429) 0.02 (+0.00) 0.00 (+0.00)
1.16 get_analysis_status 5 (0) 0 (0) 18.60 (+13.20) 3 (-2) 73 (+67) 0.02 (+0.00) 0.00 (+0.00)
1.17 get_analysis_latest_cpe 5 (0) 0 (0) 16.40 (+6.20) 11 (+2) 22 (+11) 0.02 (+0.00) 0.00 (+0.00)
1.18 list_advisory_labels 5 (0) 0 (0) 14475.00 (-3931.60) 8688 (-6137) 16783 (-11243) 0.02 (+0.00) 0.00 (+0.00)
1.19 get_sbom[sha256:a3442b37…3040057f79c70669] 5 (0) 0 (0) 1360.20 (-2973.00) 508 (-706) 3297 (-8586) 0.02 (+0.00) 0.00 (+0.00)
1.20 get_sbom_advisories[sha256:a3442b37…3040057f79c70669] 5 (0) 0 (0) 267208.81 (+19772.22) 252977 (+15713) 271312 (+16820) 0.02 (+0.00) 0.00 (+0.00)
1.21 get_sbom_packages[019c4a3e-715c-7…8ba-3cc0260ef778] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.22 get_sbom_related[019c4a3e-715c-7…8ba-3cc0260ef778] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.23 get_vulnerability[CVE-2023-39325] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.24 sbom_by_package[pkg:oci/web-ter…-bundle&tag=1.11] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.25 get_sbom_license_ids[urn:uuid:019c4a…8ba-3cc0260ef778] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.26 post_vulnerability_analyze[pkg:rpm/redhat/squid] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.27 get_purl_details[0000054a-a69b-5…520-80752db183e6] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.28 get_recommendations[pkg:maven/io.ne…8.1.redhat-00033] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.29 download_advisory[5b25cdef-428a-4…29e-fbb3415c22ab] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
1.30 get_advisory[5b25cdef-428a-4…29e-fbb3415c22ab] 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUserSlow
2.0 logon 12 (+11) 0 (0) 12.00 (+5.00) 8 (+1) 20 (+13) 0.04 (+0.04) 0.00 (+0.00)
2.1 search_licenses 12 (+11) 0 (0) 115.75 (-205.25) 6 (-315) 641 (+320) 0.04 (+0.04) 0.00 (+0.00)
2.2 search_sboms_by_license 12 (+11) 0 (0) 49.17 (-52.83) 9 (-93) 171 (+69) 0.04 (+0.04) 0.00 (+0.00)
2.3 search_purls_by_license 13 (+11) 0 (0) 23086.69 (-144482.81) 6278 (-28860) 79525 (-220476) 0.04 (+0.04) 0.00 (+0.00)
RestAPIUserDelete
3.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
3.1 delete_sbom_from_pool_sequential[100 SBOMs] 1 (0) 0 (0) 300000.00 (-1.00) 300000 (-1) 300000 (-1) 0.00 (+0.00) 0.00 (+0.00)
RestAdvisoryLableUser
4.0 logon 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
Aggregated 105 (+49) 0 (0) 22272.21 (-17667.95) 2 (-3) 300000 (-1) 0.35 (+0.16) 0.00 (+0.00)

Scenario Metrics

Transaction # Users # Times Run Average (ms) Min (ms) Max (ms) Scenarios/s Iterations
WebsiteUser 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUser 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAPIUserSlow 1 (0) 12 (+11) 23065.08 (-276964.91) 6313 (-293717) 79638 (-220392) 0.04 (+0.04) 12.00 (+11.00)
RestAPIUserDelete 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
RestAdvisoryLableUser 0 (0) 0 (0) 0.00 (+0.00) 0 (0) 0 (0) 0.00 (+0.00) 0.00 (+0.00)
Aggregated 1 (0) 12 (+11) 23065.08 (-276964.91) 6313 (-293717) 79638 (-220392) 0.04 (+0.04) 12.00 (+11.00)

Error Metrics

Method Name # Error
DELETE delete_sbom_from_pool_sequential[100 SBOMs] 1 (0) error sending request delete_sbom_from_pool_sequential[100 SBOMs]: operation timed out

📄 Full Report (Go to "Artifacts" and download report)

Vulnerability IDs (e.g., CVE-2024-12345) contain numeric segments that
should be sorted numerically rather than lexicographically. This change
adds a generated database column that stores a normalized sort key where
numeric segments are zero-padded to 19 digits (the max defined in the
CVE ID spec), enabling proper numeric ordering.

Implementation uses a PostgreSQL STORED generated column with an index,
which provides:
- Automatic computation and maintenance of sort keys for all rows
- Efficient indexed sorting without runtime overhead
- Single source of truth for the normalization logic

fixes guacsec#1811

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
@lcarva lcarva force-pushed the fix-cve-ordering branch from 28d8be6 to c3e0e85 Compare March 4, 2026 22:21
@ctron ctron enabled auto-merge March 5, 2026 09:07
@ctron
Copy link
Copy Markdown
Contributor

ctron commented Mar 5, 2026

I'm scheduling to merge this anyway. The scale tests are still not helpful to asses the impact.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 5, 2026

Codecov Report

❌ Patch coverage is 94.44444% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 68.41%. Comparing base (8f70c6e) to head (c3e0e85).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...dules/fundamental/src/vulnerability/service/mod.rs 88.88% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2020      +/-   ##
==========================================
+ Coverage   68.36%   68.41%   +0.04%     
==========================================
  Files         422      423       +1     
  Lines       24681    24698      +17     
  Branches    24681    24698      +17     
==========================================
+ Hits        16874    16896      +22     
+ Misses       6887     6877      -10     
- Partials      920      925       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ctron ctron added this pull request to the merge queue Mar 5, 2026
Merged via the queue into guacsec:main with commit 8e912cf Mar 5, 2026
6 checks passed
@github-project-automation github-project-automation Bot moved this to Done in Trustify Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

GET /api/v2/vulnerability sorted by identifier returns unexpected results

5 participants