From d0fc6a691b3ada078ebecc8e4dca5935cfe09c33 Mon Sep 17 00:00:00 2001 From: Me0wo <152751263+Sn0wo2@users.noreply.github.com> Date: Fri, 30 Oct 2026 01:03:23 +0800 Subject: [PATCH 1/3] ci(template): sync --- .github/workflows/codeql.yml | 20 +++++++++++++++++--- .github/workflows/go.yml | 34 ++++++++++++++++++++++------------ .golangci.yml | 14 ++++++++++++-- Makefile | 16 +++++++++++++++- 4 files changed, 66 insertions(+), 18 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b47e895..99e3497 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -16,9 +16,16 @@ on: branches: [ "main" ] pull_request: branches: [ "main" ] + workflow_dispatch: schedule: - cron: '23 23 * * 2' +permissions: {} + +concurrency: + group: codeql-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: analyze: name: Analyze (${{ matrix.language }}) @@ -61,7 +68,14 @@ jobs: # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 + with: + persist-credentials: false + + - uses: actions/setup-go@v7 + if: matrix.language == 'go' + with: + go-version-file: go.mod # Add any setup steps before running the `github/codeql-action/init` action. # This includes steps like installing compilers or runtimes (`actions/setup-node` @@ -71,7 +85,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -99,6 +113,6 @@ jobs: exit 1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index c30c926..b38622b 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -8,6 +8,7 @@ on: - 'go.mod' - 'go.sum' - '.golangci.yml' + - 'Makefile' - '.github/workflows/go.yml' pull_request: paths: @@ -15,9 +16,16 @@ on: - 'go.mod' - 'go.sum' - '.golangci.yml' + - 'Makefile' - '.github/workflows/go.yml' workflow_dispatch: +permissions: {} + +concurrency: + group: ci-go-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: vet-test-update-build: name: Vet, Test, Update and Build @@ -27,10 +35,12 @@ jobs: pull-requests: write steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 + with: + persist-credentials: false - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v7 with: go-version-file: 'go.mod' cache: true @@ -45,13 +55,13 @@ jobs: run: go vet $(go list ./...) - name: Run tests - run: go test -vet=off $(go list ./...) + run: make test - name: Build binary run: go build -v -o dist/QuickNote . - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: QuickNote-Binary path: dist/QuickNote @@ -67,7 +77,7 @@ jobs: - name: Create Pull Request with update dependencies if: steps.git-check.outputs.changed == 'true' && github.ref == 'refs/heads/main' - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@v8 with: commit-message: "chore(backend): update dependencies" title: "chore(backend): update dependencies" @@ -85,21 +95,21 @@ jobs: pull-requests: write steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 + with: + persist-credentials: false - name: Setup Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v7 with: go-version-file: 'go.mod' cache: true - name: Run golangci-lint with auto-fix - uses: golangci/golangci-lint-action@v8 + uses: golangci/golangci-lint-action@v9 with: version: latest args: --fix - cache-key: golangci-lint - cache: true - name: Check for file changes id: git-check @@ -112,7 +122,7 @@ jobs: - name: Create Pull Request with lint fixes if: steps.git-check.outputs.changed == 'true' && github.ref == 'refs/heads/main' - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@v8 with: commit-message: "chore(backend): fix lint issues" title: "chore(backend): fix lint issues" @@ -120,4 +130,4 @@ jobs: branch: "chore/go-lint-fixes" base: main signoff: true - sign-commits: true \ No newline at end of file + sign-commits: true diff --git a/.golangci.yml b/.golangci.yml index ab588fe..a623061 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,9 +1,11 @@ version: "2" linters: + default: none enable: - govet - errcheck + - ineffassign - staticcheck - unused - nilnesserr @@ -20,9 +22,10 @@ linters: - whitespace - tagalign - dupl + - dogsled - nolintlint - maintidx - - wsl + - wsl_v5 - decorder - asciicheck - bidichk @@ -44,6 +47,7 @@ linters: - ginkgolinter - gocheckcompilerdirectives - gochecksumtype + - gosec - gomoddirectives - goprintffuncname - importas @@ -63,6 +67,7 @@ linters: - protogetter - reassign - recvcheck + - revive - rowserrcheck - sloglint - spancheck @@ -81,6 +86,12 @@ linters: - misspell - tparallel + settings: + revive: + enable-default-rules: false + rules: + - name: var-declaration + run: tests: true concurrency: 4 @@ -91,7 +102,6 @@ run: issues: max-issues-per-linter: 0 uniq-by-line: true - fix: true formatters: enable: diff --git a/Makefile b/Makefile index 55968a9..a4bece1 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ ifeq ($(OS),Windows_NT) RM_RF := if exist static ( rmdir /s /q static ) endif -.PHONY: test_release run_docker update_depends update_frontend_depends build +.PHONY: test_release run_docker update_depends update_frontend_depends build lint lint-fix test security ci test_release: @echo "<<< Starting test release" @@ -61,3 +61,17 @@ build: -asmflags="-trimpath" main.go @echo "<<< Build complete: ./QuicKNote$(EXT)" + +lint: + go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.15.0 run + +lint-fix: + go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.15.0 run --fix + +test: + go test $(if $(filter 1,$(shell go env CGO_ENABLED)),-race) ./... + +security: + go run golang.org/x/vuln/cmd/govulncheck@latest ./... + +ci: lint test security From 6a1fbc71f4bd850b7bac4d0487e88ca1ec77158d Mon Sep 17 00:00:00 2001 From: Me0wo <152751263+Sn0wo2@users.noreply.github.com> Date: Fri, 30 Oct 2026 01:55:58 +0800 Subject: [PATCH 2/3] fix(ci): restore QuickNote checks --- .github/workflows/go.yml | 39 +++++++---------------------------- internal/note/instance.go | 1 + internal/note/marshal.go | 9 +++++++- internal/note/marshal_test.go | 13 ++++++------ pkg/compress/flate.go | 9 +++++++- pkg/config/config.go | 5 +++-- pkg/helper/helper.go | 8 ++----- pkg/log/zap.go | 2 +- 8 files changed, 36 insertions(+), 50 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b38622b..4899fb9 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -31,8 +31,7 @@ jobs: name: Vet, Test, Update and Build runs-on: ubuntu-latest permissions: - contents: write - pull-requests: write + contents: read steps: - name: Checkout repository uses: actions/checkout@v7 @@ -42,14 +41,11 @@ jobs: - name: Setup Go uses: actions/setup-go@v7 with: - go-version-file: 'go.mod' + go-version: stable cache: true - - name: Update dependencies - run: go get all - - - name: Update go.sum - run: go mod tidy + - name: Verify dependencies + run: go mod download && go mod verify - name: Run vet run: go vet $(go list ./...) @@ -66,27 +62,6 @@ jobs: name: QuickNote-Binary path: dist/QuickNote - - name: Check for file changes - id: git-check - run: | - if git diff --exit-code; then - echo "changed=false" >> $GITHUB_OUTPUT - else - echo "changed=true" >> $GITHUB_OUTPUT - fi - - - name: Create Pull Request with update dependencies - if: steps.git-check.outputs.changed == 'true' && github.ref == 'refs/heads/main' - uses: peter-evans/create-pull-request@v8 - with: - commit-message: "chore(backend): update dependencies" - title: "chore(backend): update dependencies" - body: "The `Update dependencies` action wants to apply these fixes." - branch: "chore/go-dependencies" - base: main - signoff: true - sign-commits: true - lint: name: Lint and Auto-fix runs-on: ubuntu-latest @@ -102,11 +77,11 @@ jobs: - name: Setup Go uses: actions/setup-go@v7 with: - go-version-file: 'go.mod' + go-version: stable cache: true - name: Run golangci-lint with auto-fix - uses: golangci/golangci-lint-action@v9 + uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a with: version: latest args: --fix @@ -122,7 +97,7 @@ jobs: - name: Create Pull Request with lint fixes if: steps.git-check.outputs.changed == 'true' && github.ref == 'refs/heads/main' - uses: peter-evans/create-pull-request@v8 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 with: commit-message: "chore(backend): fix lint issues" title: "chore(backend): fix lint issues" diff --git a/internal/note/instance.go b/internal/note/instance.go index 49a4cc7..df3d8ee 100644 --- a/internal/note/instance.go +++ b/internal/note/instance.go @@ -13,6 +13,7 @@ func InitNoteSchema() error { func GetNote(nid string) (Note, error) { var note Note + err := orm.Instance.Get().First(¬e, "n_id = ?", nid).Error return note, err diff --git a/internal/note/marshal.go b/internal/note/marshal.go index edbeabd..d452d56 100644 --- a/internal/note/marshal.go +++ b/internal/note/marshal.go @@ -14,6 +14,7 @@ const ( magicVersion = 1 fieldTitle = 1 fieldContent = 2 + maxFieldSize = 64 << 20 ) // magicHeader First 2 bytes of SHA-256 hash of "QuickNote" @@ -38,6 +39,7 @@ func (n *Note) Encode() error { writeField(fieldContent, n.Content) var err error + n.Data, err = compress.FlateCompress(buf.Bytes()) n.Title, n.Content = nil, nil @@ -85,7 +87,12 @@ func (n *Note) Decode(data []byte) error { return fmt.Errorf("read field %d length: %w", id, err) } - value := make([]byte, binary.LittleEndian.Uint32(buf)) + fieldLen := binary.LittleEndian.Uint32(buf) + if fieldLen > maxFieldSize || int64(fieldLen) > int64(r.Len()) { + return fmt.Errorf("field %d length exceeds remaining data", id) + } + + value := make([]byte, int(fieldLen)) if _, err = io.ReadFull(r, value); err != nil { return fmt.Errorf("read field %d: %w", id, err) } diff --git a/internal/note/marshal_test.go b/internal/note/marshal_test.go index cdf6295..e304381 100644 --- a/internal/note/marshal_test.go +++ b/internal/note/marshal_test.go @@ -2,19 +2,18 @@ package note import ( "bytes" - "math/rand/v2" "testing" ) -func generateRandomNote() *Note { +func generateNote() *Note { return &Note{ - Title: bytes.Repeat([]byte{'a'}, rand.IntN(100)+50), - Content: bytes.Repeat([]byte{'b'}, rand.IntN(1000)+500), + Title: bytes.Repeat([]byte{'a'}, 100), + Content: bytes.Repeat([]byte{'b'}, 1000), } } func BenchmarkEncode(b *testing.B) { - note := generateRandomNote() + note := generateNote() b.ResetTimer() @@ -24,7 +23,7 @@ func BenchmarkEncode(b *testing.B) { } func BenchmarkDecode(b *testing.B) { - note := generateRandomNote() + note := generateNote() if err := note.Encode(); err != nil { b.Fatalf("Failed to encode note for benchmark: %v", err) } @@ -40,7 +39,7 @@ func BenchmarkDecode(b *testing.B) { } func BenchmarkEncodeDecode(b *testing.B) { - note := generateRandomNote() + note := generateNote() b.ResetTimer() diff --git a/pkg/compress/flate.go b/pkg/compress/flate.go index 992223b..c314fd6 100644 --- a/pkg/compress/flate.go +++ b/pkg/compress/flate.go @@ -3,9 +3,12 @@ package compress import ( "bytes" "compress/flate" + "fmt" "io" ) +const maxDecompressedSize = 64 << 20 + func FlateCompress(data []byte) ([]byte, error) { var b bytes.Buffer // level: flate.DefaultCompression, flate.BestSpeed, etc. @@ -32,10 +35,14 @@ func FlateDecompress(compressed []byte) ([]byte, error) { var out bytes.Buffer - _, err := io.Copy(&out, reader) + _, err := io.Copy(&out, io.LimitReader(reader, maxDecompressedSize+1)) if err != nil { return nil, err } + if out.Len() > maxDecompressedSize { + return nil, fmt.Errorf("decompressed data exceeds %d bytes", maxDecompressedSize) + } + return out.Bytes(), nil } diff --git a/pkg/config/config.go b/pkg/config/config.go index 6011fc9..3721bba 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -24,6 +24,7 @@ func Init() error { cfgPath = "./data/config.yml" } + // #nosec G304 G703 -- cfgPath is the user's configured location for the app config. cf, err := os.ReadFile(cfgPath) if err != nil { return err @@ -52,7 +53,7 @@ func (c *Config) String() string { func validate(cfg any) error { v := reflect.ValueOf(cfg) - if v.Kind() == reflect.Ptr { + if v.Kind() == reflect.Pointer { v = v.Elem() } @@ -82,7 +83,7 @@ func validate(cfg any) error { isEmpty = value.Uint() == 0 case reflect.Float32, reflect.Float64: isEmpty = value.Float() == 0 - case reflect.Ptr, reflect.Interface: + case reflect.Pointer, reflect.Interface: isEmpty = value.IsNil() case reflect.Slice, reflect.Map, reflect.Array: isEmpty = value.Len() == 0 diff --git a/pkg/helper/helper.go b/pkg/helper/helper.go index e0565c4..2b19c32 100644 --- a/pkg/helper/helper.go +++ b/pkg/helper/helper.go @@ -1,13 +1,9 @@ package helper -import ( - "unsafe" -) - func BytesToString(v []byte) string { - return *(*string)(unsafe.Pointer(&v)) + return string(v) } func StringToBytes(v string) []byte { - return unsafe.Slice(unsafe.StringData(v), len(v)) + return []byte(v) } diff --git a/pkg/log/zap.go b/pkg/log/zap.go index 42cba87..3de4219 100644 --- a/pkg/log/zap.go +++ b/pkg/log/zap.go @@ -22,7 +22,7 @@ func Init() { panic("failed to resolve log dir path: " + err.Error()) } - if err := os.MkdirAll(logDir, 0o755); err != nil { + if err := os.MkdirAll(logDir, 0o750); err != nil { panic("failed to create log directory: " + err.Error()) } From 9466d38a098fc2f4c17fe0c45ca1c50f5d06df20 Mon Sep 17 00:00:00 2001 From: Me0wo <152751263+Sn0wo2@users.noreply.github.com> Date: Fri, 30 Oct 2026 02:13:34 +0800 Subject: [PATCH 3/3] chore(ci): pin actions and gate race tests --- .github/workflows/codeql.yml | 8 ++++---- .github/workflows/go.yml | 14 +++++++------- Makefile | 10 +++++++++- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 99e3497..416a9a3 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -68,11 +68,11 @@ jobs: # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - - uses: actions/setup-go@v7 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 if: matrix.language == 'go' with: go-version-file: go.mod @@ -85,7 +85,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v4 + uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} @@ -113,6 +113,6 @@ jobs: exit 1 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 + uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4 with: category: "/language:${{matrix.language}}" diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4899fb9..ea414a4 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -34,12 +34,12 @@ jobs: contents: read steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - name: Setup Go - uses: actions/setup-go@v7 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 with: go-version: stable cache: true @@ -57,7 +57,7 @@ jobs: run: go build -v -o dist/QuickNote . - name: Upload artifact - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7 with: name: QuickNote-Binary path: dist/QuickNote @@ -70,18 +70,18 @@ jobs: pull-requests: write steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 with: persist-credentials: false - name: Setup Go - uses: actions/setup-go@v7 + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7 with: go-version: stable cache: true - name: Run golangci-lint with auto-fix - uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a + uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9 with: version: latest args: --fix @@ -97,7 +97,7 @@ jobs: - name: Create Pull Request with lint fixes if: steps.git-check.outputs.changed == 'true' && github.ref == 'refs/heads/main' - uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 + uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8 with: commit-message: "chore(backend): fix lint issues" title: "chore(backend): fix lint issues" diff --git a/Makefile b/Makefile index a4bece1..4bb85e6 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,14 @@ RM_RF := rm -rf ./static UNAME_S := $(shell uname -s) +RACE_PLATFORMS := \ + linux/amd64 linux/arm64 linux/ppc64le linux/s390x \ + freebsd/amd64 netbsd/amd64 darwin/amd64 darwin/arm64 windows/amd64 +GO_TEST_PLATFORM := $(shell go env GOOS)/$(shell go env GOARCH) +GO_TEST_RACE := $(if $(and \ + $(filter 1,$(shell go env CGO_ENABLED)), \ + $(filter $(GO_TEST_PLATFORM),$(RACE_PLATFORMS))),-race) + ifeq ($(OS),Windows_NT) EXT := .exe MOVE := move @@ -69,7 +77,7 @@ lint-fix: go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.15.0 run --fix test: - go test $(if $(filter 1,$(shell go env CGO_ENABLED)),-race) ./... + go test $(GO_TEST_RACE) ./... security: go run golang.org/x/vuln/cmd/govulncheck@latest ./...