Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/run-static-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2026 Specter Ops, Inc.
#
# Licensed under the Apache License, Version 2.0
# 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

name: Run Code Static Analysis

on:
pull_request:
branches:
- "main"
- "stage/**"
types:
- "opened"
- "synchronize"

jobs:
static_analysis:
runs-on: ubuntu-latest
steps:
- name: Checkout source code for this repository
uses: actions/checkout@v4

- name: Install Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true
check-latest: true

- name: Run Analysis
run: |
go tool golangci-lint run
40 changes: 40 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
version: "2"
linters:
disable:
- errcheck
Comment on lines +3 to +4
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Do not disable the errcheck linter.

Disabling errcheck removes detection of unchecked error returns, which is a common source of correctness bugs and security vulnerabilities in Go. Unchecked errors can lead to silent failures, data corruption, resource leaks, and security issues.

If specific error checks need to be excluded, use targeted exclusions rather than disabling the entire linter.

✅ Proposed fix: Enable errcheck with targeted exclusions if needed
-linters:
-  disable:
-    - errcheck
+linters:
+  enable:
+    - errcheck
+# If specific exclusions are needed:
+# linters-settings:
+#   errcheck:
+#     exclude-functions:
+#       - fmt.Print.*
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
disable:
- errcheck
linters:
enable:
- errcheck
# If specific exclusions are needed:
# linters-settings:
# errcheck:
# exclude-functions:
# - fmt.Print.*
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.golangci.yml around lines 3 - 4, The configuration currently disables the
entire errcheck linter; re-enable errcheck (remove the "- errcheck" entry) and,
if certain unchecked errors must be ignored, add targeted exclusions instead
using golangci-lint's configuration (e.g., add linters-settings for errcheck or
use exclude/exclude-rules or excludePatterns to silence specific files,
functions, or error-return patterns). Ensure the symbol "errcheck" is not listed
under disable and create precise exclude rules for known safe exceptions rather
than disabling the linter globally.

settings:
staticcheck:
checks:
- all
- "-QF1012"
- "-QF1008"
- "-ST1003"
- "-ST1021"
- "-ST1020"
- "-ST1000"
# Note: ElementId/StartElementId/EndElementId (internalRelationship fields) are the Neo4j v6 opaque tokens,
# but we use the deprecated Id/StartId/EndId fields for graph.ID because existing Cypher queries use
# id() function which matches the int64 ID fields.
- "-SA1019"
exclusions:
rules:
- path: integration/harness.go
linters:
- unused
- path: cypher/models/pgsql/translate/selectivity.go
linters:
- unused
- path: _test\.go
linters:
- staticcheck
formatters:
enable:
- gofmt
- goimports
exclusions:
paths:
- _test\.go
output:
formats:
json:
path: golangci-report.json
4 changes: 2 additions & 2 deletions cmd/benchmark/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ func main() {
driver = flag.String("driver", "pg", "database driver (pg, neo4j)")
connStr = flag.String("connection", "", "database connection string (or PG_CONNECTION_STRING)")
iterations = flag.Int("iterations", 10, "timed iterations per scenario")
output = flag.String("output", "", "markdown output file (default: stdout)")
datasetDir = flag.String("dataset-dir", "integration/testdata", "path to testdata directory")
output = flag.String("output", "", "markdown output file (default: stdout)")
datasetDir = flag.String("dataset-dir", "integration/testdata", "path to testdata directory")
localDataset = flag.String("local-dataset", "", "additional local dataset (e.g. local/phantom)")
onlyDataset = flag.String("dataset", "", "run only this dataset (e.g. diamond, local/phantom)")
)
Expand Down
2 changes: 1 addition & 1 deletion container/bfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func WriteZoneBFSTree(zoneNodes graph.NodeSet, ts Triplestore, scratchPath strin
defer scratchFile.Close()
defer scratchFileWriter.Close()

for zoneNodeID, _ := range zoneNodes {
for zoneNodeID := range zoneNodes {
TSBFS(
ts,
zoneNodeID.Uint64(),
Expand Down
4 changes: 2 additions & 2 deletions container/pacmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ func (s *packedBucket) Compact() {
s.merge()
} else {
var (
newUniverseMin uint64 = s.pending[0].key
newUniverseMax uint64 = s.pending[len(s.pending)-1].key
newUniverseMin = s.pending[0].key
newUniverseMax = s.pending[len(s.pending)-1].key
)

// Allocate the key and value containers
Expand Down
2 changes: 1 addition & 1 deletion cypher/frontend/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ type MatchVisitor struct {
}

func NewMatchVisitor(ctx *parser.OC_MatchContext) *MatchVisitor {
optional := false
var optional bool

if HasTokens(ctx, parser.CypherLexerOPTIONAL) {
optional = true
Expand Down
2 changes: 1 addition & 1 deletion cypher/models/pgsql/translate/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ func rewriteStringWildCardLiteral(expression pgsql.Expression) (pgsql.Expression
if strValue, typeOK := typedExpression.Value.(string); !typeOK {
return nil, fmt.Errorf("expected a string literal but received type: %T", typedExpression.Value)
} else {
rewritten := strings.Replace(strValue, "_", "\\_", -1)
rewritten := strings.ReplaceAll(strValue, "_", "\\_")
return pgsql.NewLiteral(rewritten, pgsql.Text), nil
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/neo4j/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"strings"

"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/neo4j/neo4j-go-driver/v6/neo4j"
"github.com/specterops/dawgs/graph"
"github.com/specterops/dawgs/util/size"
)
Expand Down
16 changes: 8 additions & 8 deletions drivers/neo4j/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"time"

"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/neo4j/neo4j-go-driver/v6/neo4j"
"github.com/specterops/dawgs/graph"
"github.com/specterops/dawgs/util/channels"
"github.com/specterops/dawgs/util/size"
Expand Down Expand Up @@ -64,11 +64,11 @@ func (s *driver) BatchOperation(ctx context.Context, batchDelegate graph.BatchDe
Timeout: s.defaultTransactionTimeout,
}

session = s.driver.NewSession(writeCfg())
session = s.driver.NewSession(ctx, writeCfg())
batch = newBatchOperation(ctx, session, cfg, s.writeFlushSize, config.BatchSize, s.graphQueryMemoryLimit)
)

defer session.Close()
defer session.Close(ctx)
defer batch.Close()

if err := batchDelegate(batch); err != nil {
Expand All @@ -79,7 +79,7 @@ func (s *driver) BatchOperation(ctx context.Context, batchDelegate graph.BatchDe
}

func (s *driver) Close(ctx context.Context) error {
return s.driver.Close()
return s.driver.Close(ctx)
}

func (s *driver) transaction(ctx context.Context, txDelegate graph.TransactionDelegate, session neo4j.Session, options []graph.TransactionOption) error {
Expand Down Expand Up @@ -110,15 +110,15 @@ func (s *driver) transaction(ctx context.Context, txDelegate graph.TransactionDe
}

func (s *driver) ReadTransaction(ctx context.Context, txDelegate graph.TransactionDelegate, options ...graph.TransactionOption) error {
session := s.driver.NewSession(readCfg())
defer session.Close()
session := s.driver.NewSession(ctx, readCfg())
defer session.Close(ctx)

return s.transaction(ctx, txDelegate, session, options)
}

func (s *driver) WriteTransaction(ctx context.Context, txDelegate graph.TransactionDelegate, options ...graph.TransactionOption) error {
session := s.driver.NewSession(writeCfg())
defer session.Close()
session := s.driver.NewSession(ctx, writeCfg())
defer session.Close(ctx)

return s.transaction(ctx, txDelegate, session, options)
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/neo4j/mapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package neo4j
import (
"time"

"github.com/neo4j/neo4j-go-driver/v5/neo4j/dbtype"
"github.com/neo4j/neo4j-go-driver/v6/neo4j/dbtype"
"github.com/specterops/dawgs/graph"
)

Expand Down
2 changes: 1 addition & 1 deletion drivers/neo4j/neo4j.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"math"
"net/url"

"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"github.com/neo4j/neo4j-go-driver/v6/neo4j"
"github.com/specterops/dawgs"
"github.com/specterops/dawgs/graph"
"github.com/specterops/dawgs/util/channels"
Expand Down
2 changes: 1 addition & 1 deletion drivers/neo4j/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package neo4j
import (
"context"

neo4j_core "github.com/neo4j/neo4j-go-driver/v5/neo4j"
neo4j_core "github.com/neo4j/neo4j-go-driver/v6/neo4j"
"github.com/specterops/dawgs/graph"
"github.com/specterops/dawgs/query"
"github.com/specterops/dawgs/query/neo4j"
Expand Down
2 changes: 1 addition & 1 deletion drivers/neo4j/relationship.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"fmt"

neo4j_core "github.com/neo4j/neo4j-go-driver/v5/neo4j"
neo4j_core "github.com/neo4j/neo4j-go-driver/v6/neo4j"
"github.com/specterops/dawgs/graph"
"github.com/specterops/dawgs/query"
"github.com/specterops/dawgs/query/neo4j"
Expand Down
8 changes: 5 additions & 3 deletions drivers/neo4j/result.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package neo4j

import (
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"context"

"github.com/neo4j/neo4j-go-driver/v6/neo4j"
"github.com/specterops/dawgs/graph"
)

Expand Down Expand Up @@ -42,7 +44,7 @@ func (s *internalResult) Scan(targets ...any) error {
}

func (s *internalResult) Next() bool {
return s.driverResult.Next()
return s.driverResult.Next(context.Background())
}

func (s *internalResult) Error() error {
Expand All @@ -61,6 +63,6 @@ func (s *internalResult) Error() error {
func (s *internalResult) Close() {
if s.driverResult != nil {
// Ignore the results of this call. This is called only as a best-effort attempt at a close
s.driverResult.Consume()
s.driverResult.Consume(context.Background())
}
}
2 changes: 1 addition & 1 deletion drivers/neo4j/result_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"testing"
"time"

"github.com/neo4j/neo4j-go-driver/v5/neo4j/dbtype"
"github.com/neo4j/neo4j-go-driver/v6/neo4j/dbtype"
"github.com/specterops/dawgs/graph"
"github.com/stretchr/testify/require"
)
Expand Down
16 changes: 8 additions & 8 deletions drivers/neo4j/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/specterops/dawgs/query/neo4j"
"github.com/specterops/dawgs/util/size"

neo4j_core "github.com/neo4j/neo4j-go-driver/v5/neo4j"
neo4j_core "github.com/neo4j/neo4j-go-driver/v6/neo4j"
"github.com/specterops/dawgs/graph"
"github.com/specterops/dawgs/query"
)
Expand All @@ -33,7 +33,7 @@ type neo4jTransaction struct {
cfg graph.TransactionConfig
ctx context.Context
session neo4j_core.Session
innerTx neo4j_core.Transaction
innerTx neo4j_core.ExplicitTransaction
writes int
writeFlushSize int
batchWriteSize int
Expand Down Expand Up @@ -143,16 +143,16 @@ func (s *neo4jTransaction) flushTx() error {
s.innerTx = nil
}()

if err := s.innerTx.Commit(); err != nil {
if err := s.innerTx.Commit(s.ctx); err != nil {
return err
}

return nil
}

func (s *neo4jTransaction) currentTx() neo4j_core.Transaction {
func (s *neo4jTransaction) currentTx() neo4j_core.ExplicitTransaction {
if s.innerTx == nil {
if newTx, err := s.session.BeginTransaction(neo4j_core.WithTxTimeout(s.cfg.Timeout)); err != nil {
if newTx, err := s.session.BeginTransaction(s.ctx, neo4j_core.WithTxTimeout(s.cfg.Timeout)); err != nil {
return newErrorTransactionWrapper(err)
} else {
s.innerTx = newTx
Expand Down Expand Up @@ -337,7 +337,7 @@ func (s *neo4jTransaction) Raw(stmt string, params map[string]any) graph.Result
slog.Info(fmt.Sprintf("%s - %s", stmt, prettyParameters.String()), "dawgs_db_driver", DriverName)
}

driverResult, err := s.currentTx().Run(stmt, params)
driverResult, err := s.currentTx().Run(s.ctx, stmt, params)
return NewResult(stmt, err, driverResult)
}

Expand Down Expand Up @@ -366,7 +366,7 @@ func (s *neo4jTransaction) Commit() error {
txRef := s.innerTx
s.innerTx = nil

return txRef.Commit()
return txRef.Commit(s.ctx)
}

return nil
Expand All @@ -377,7 +377,7 @@ func (s *neo4jTransaction) Close() error {
txRef := s.innerTx
s.innerTx = nil

return txRef.Close()
return txRef.Close(s.ctx)
}

return nil
Expand Down
12 changes: 7 additions & 5 deletions drivers/neo4j/wrapper.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package neo4j

import (
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
"context"

"github.com/neo4j/neo4j-go-driver/v6/neo4j"
)

type errorTransactionWrapper struct {
Expand All @@ -14,18 +16,18 @@ func newErrorTransactionWrapper(err error) errorTransactionWrapper {
}
}

func (s errorTransactionWrapper) Run(cypher string, params map[string]any) (neo4j.Result, error) {
func (s errorTransactionWrapper) Run(ctx context.Context, cypher string, params map[string]any) (neo4j.Result, error) {
return nil, s.err
}

func (s errorTransactionWrapper) Commit() error {
func (s errorTransactionWrapper) Commit(ctx context.Context) error {
return s.err
}

func (s errorTransactionWrapper) Rollback() error {
func (s errorTransactionWrapper) Rollback(ctx context.Context) error {
return s.err
}

func (s errorTransactionWrapper) Close() error {
func (s errorTransactionWrapper) Close(ctx context.Context) error {
return s.err
}
Loading
Loading