Fixed issue searching software versions (#34770)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #34713 Fix for unreleased but. Needs to be cherry picked into 4.76.0 # Checklist for submitter ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually For unreleased bug fixes in a release candidate, one of: - [x] Confirmed that the fix is not expected to adversely impact load test results
This commit is contained in:
@@ -1407,13 +1407,15 @@ func selectSoftwareSQL(opts fleet.SoftwareListOptions) (string, []interface{}, e
|
||||
goqu.I("software_cve").As("scv"),
|
||||
goqu.On(goqu.I("s.id").Eq(goqu.I("scv.software_id"))),
|
||||
)
|
||||
} else if !opts.WithoutVulnerabilityDetails || opts.IncludeCVEScores {
|
||||
// Only LEFT JOIN software_cve if we need CVE details in the list OR if we need CVE scores.
|
||||
// When WithoutVulnerabilityDetails=true AND IncludeCVEScores=false, we can skip this join
|
||||
// entirely in the subquery. The outer query will fetch CVEs only for the paginated results,
|
||||
// which is much more efficient.
|
||||
// However, if IncludeCVEScores=true, we MUST include the join because we need to select
|
||||
// scv.resolved_in_version and other scv columns for ordering/filtering.
|
||||
} else if !opts.WithoutVulnerabilityDetails || opts.IncludeCVEScores || opts.ListOptions.MatchQuery != "" {
|
||||
// LEFT JOIN software_cve if:
|
||||
// 1. We need CVE details in the list (!WithoutVulnerabilityDetails), OR
|
||||
// 2. We need CVE scores for ordering/filtering (IncludeCVEScores), OR
|
||||
// 3. We have a search query (MatchQuery) that might be searching for CVEs
|
||||
//
|
||||
// When WithoutVulnerabilityDetails=true AND IncludeCVEScores=false AND MatchQuery is empty,
|
||||
// we can skip this join entirely in the subquery. The outer query will fetch CVEs only for
|
||||
// the paginated results, which is much more efficient.
|
||||
ds = ds.
|
||||
LeftJoin(
|
||||
goqu.I("software_cve").As("scv"),
|
||||
|
||||
@@ -786,6 +786,40 @@ func testSoftwareList(t *testing.T, ds *Datastore) {
|
||||
listSoftwareCheckCount(t, ds, 0, 0, opts, true)
|
||||
})
|
||||
|
||||
t.Run("filters by CVE with WithoutVulnerabilityDetails", func(t *testing.T) {
|
||||
// Regression test for https://github.com/fleetdm/fleet/issues/34713
|
||||
// When WithoutVulnerabilityDetails=true and IncludeCVEScores=false,
|
||||
// the software_cve table is not joined in the subquery, but the WHERE clause
|
||||
// still tries to reference scv.cve, causing "Unknown column 'scv.cve'" error.
|
||||
opts := fleet.SoftwareListOptions{
|
||||
ListOptions: fleet.ListOptions{
|
||||
MatchQuery: "CVE-2022-0001",
|
||||
},
|
||||
WithoutVulnerabilityDetails: true,
|
||||
IncludeCVEScores: false,
|
||||
}
|
||||
software := listSoftwareCheckCount(t, ds, 1, 1, opts, true)
|
||||
expectedFoo001 := fleet.Software{
|
||||
Name: "foo",
|
||||
Version: "0.0.1",
|
||||
Source: "chrome_extensions",
|
||||
}
|
||||
require.Len(t, software, 1)
|
||||
require.Equal(t, expectedFoo001.Name, software[0].Name)
|
||||
require.Equal(t, expectedFoo001.Version, software[0].Version)
|
||||
require.Equal(t, expectedFoo001.Source, software[0].Source)
|
||||
|
||||
// Test with partial CVE
|
||||
opts.ListOptions.MatchQuery = "0002"
|
||||
software = listSoftwareCheckCount(t, ds, 1, 1, opts, true)
|
||||
require.Len(t, software, 1)
|
||||
require.Equal(t, expectedFoo001.Name, software[0].Name)
|
||||
|
||||
// Test with unknown CVE
|
||||
opts.ListOptions.MatchQuery = "CVE-2022-0000"
|
||||
listSoftwareCheckCount(t, ds, 0, 0, opts, true)
|
||||
})
|
||||
|
||||
t.Run("filters by query", func(t *testing.T) {
|
||||
// query by name (case insensitive)
|
||||
opts := fleet.SoftwareListOptions{
|
||||
|
||||
Reference in New Issue
Block a user