From ca0724c1211ba296e006effdaabeff87cbb3c890 Mon Sep 17 00:00:00 2001 From: Wasabules <39313803+Wasabules@users.noreply.github.com> Date: Sat, 5 Sep 2026 22:52:22 +0200 Subject: [PATCH] ci(security): dependabot, CodeQL, audits bloquants et provenance de build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alignement de la chaîne CI/CD sur SnmpLens, qui était nettement mieux outillé côté analyse, puis ajout de ce qui manquait aux deux. Repris de SnmpLens ------------------ - dependabot.yml : mises à jour hebdomadaires gomod, npm et github-actions. C'est ce qui rend les actions épinglées par SHA maintenables — sans lui, un épinglage gèle une action au commit du jour où il a été écrit, correctifs de sécurité compris. Les x/* et la chaîne Svelte sont groupés : ces paquets sont verrouillés les uns aux autres, des PR séparées se cassent mutuellement la CI. - codeql.yml : analyse Go et JavaScript/TypeScript, requêtes security-and-quality, plus un passage hebdomadaire. Aucun autre outil ici ne cherche un motif exploitable dans le code qu'on écrit : go vet et staticcheck cherchent des erreurs, govulncheck et npm audit des dépendances vulnérables connues. Le cron compte autant que le déclenchement au push — une requête ajoutée à CodeQL après qu'un commit a atterri ne le verrait jamais autrement. - dependency-review sur les PR : bloque l'introduction d'une dépendance portant un avis de sécurité. govulncheck ne sait pas faire ça, il rapporte sur ce qui est déjà fusionné. - govulncheck et npm audit --audit-level=high en CI, sans « || true ». - staticcheck et vérification que go.mod est tidy. - wails build sur les trois plateformes. C'est la différence la plus lourde de conséquences : la CI ne compilait jamais l'application complète, seulement go vet/test et le build frontend séparément. Elle pouvait donc être verte avec un wails build cassé, et la casse n'apparaissait qu'au push du tag — c'est-à-dire quand c'est déjà une release ratée. Ajouté au-delà des deux projets ------------------------------- - Attestation de provenance des artefacts (actions/attest-build-provenance). Elle répond à une question que la signature Ed25519 du manifeste ne couvre pas : cette signature prouve que les sommes ont été signées par le détenteur de la clé, pas que les binaires ont été produits par ce dépôt via ce workflow. Vérifiable sans faire confiance à notre outillage : gh attestation verify --repo Wasabules/SyslogStudio - persist-credentials: false sur tous les checkouts. Aucun job ne pousse ; laisser le token dans .git/config l'expose au code tiers exécuté ensuite. - Groupes de concurrence : les pushes obsolètes d'une même PR sont annulés, ceux de main jamais — chaque commit de la branche par défaut garde son verdict. - Actions remontées aux versions courantes (checkout v7, setup-go v7, setup-node v7, upload-artifact v7, download-artifact v8, gh-release v3). Pièges rencontrés, et pourquoi le résultat est ce qu'il est ----------------------------------------------------------- main.go porte //go:embed all:frontend/dist et ce répertoire est gitignoré, donc tout ce qui compile le paquet main échoue sur « pattern all:frontend/dist: no matching files found ». staticcheck s'arrête net ; govulncheck est plus insidieux, il continue et ne rapporte que sur les sous-paquets — main paraissait sain parce qu'il n'avait jamais été regardé. D'où le placeholder dans les deux jobs. Même logique sur Linux pour les tags de build : sans libgtk/libwebkit et sans -tags webkit2_41, les paquets Wails ne compilent pas et disparaissent du scan en silence. L'étape « Confirm the tree builds before scanning it » est le fil-piège qui transforme ce faux négatif en échec visible. Corrige au passage la seule remontée de staticcheck sur l'arbre existant : une affectation morte dans framing_test.go (SA4006), écrasée à la ligne suivante. --- .github/dependabot.yml | 45 +++++++ .github/workflows/ci.yml | 207 +++++++++++++++++++++++++++++--- .github/workflows/codeql.yml | 88 ++++++++++++++ .github/workflows/release.yml | 65 +++++++--- internal/syslog/framing_test.go | 6 +- 5 files changed, 377 insertions(+), 34 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/codeql.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..98213f5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,45 @@ +version: 2 + +# Dependabot is what makes SHA-pinned actions maintainable. Pinning without it +# means the pins rot: an action stays frozen at whatever commit was current the +# day someone wrote it, security fixes included. +# +# This covers version updates. Dependabot *security* updates (the automatic PRs +# for a newly disclosed advisory) are a separate repository setting and are +# already enabled. +updates: + - package-ecosystem: gomod + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 + groups: + # golang.org/x/* move together and are almost always safe; one PR rather + # than five keeps the noise down without hiding anything. + golang-x: + patterns: + - golang.org/x/* + + - package-ecosystem: npm + directory: /frontend + schedule: + interval: weekly + open-pull-requests-limit: 5 + groups: + # The Svelte 3 / Vite 3 toolchain moves as a unit — svelte, svelte-check, + # svelte-preprocess and the Vite plugin are version-locked against each + # other, so separate PRs for them just fail each other's CI. + svelte-toolchain: + patterns: + - svelte + - svelte-* + - "@sveltejs/*" + - vite + + # The workflows pin actions by commit SHA, so this is the only thing that + # ever moves them. + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + open-pull-requests-limit: 5 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75e1df6..8718dfa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,23 +11,70 @@ on: permissions: contents: read +# Superseded pushes to the same pull request are pointless work. Pushes to main +# are never cancelled: every commit on the default branch gets its own verdict. +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + jobs: - backend: - name: Go (${{ matrix.os }}) + # The full application build, on every platform we ship. This is deliberately + # `wails build` and not a bare `go build`: the CLI regenerates the JS bindings + # and builds the frontend before compiling, so this is the only check that + # covers the whole pipeline the release workflow runs. Without it, CI can be + # green while `wails build` is broken, and the breakage only surfaces when a + # tag is pushed — which is to say, when it is already a failed release. + build: + name: Build & test (${{ matrix.os }}) runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: - os: [ubuntu-24.04, windows-latest, macos-latest] + include: + - os: ubuntu-24.04 + platform: linux/amd64 + - os: windows-latest + platform: windows/amd64 + - os: macos-latest + platform: darwin/universal + steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup Go + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: + # From go.mod, so the toolchain has exactly one source of truth. go-version-file: go.mod + + - name: Setup Node.js + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: "20" + cache: npm + cache-dependency-path: frontend/package-lock.json + - name: Install Linux dependencies if: runner.os == 'Linux' run: sudo apt-get update && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev pkg-config - - name: Create frontend/dist placeholder for go:embed - run: mkdir -p frontend/dist && touch frontend/dist/.gitkeep + + - name: Install Wails CLI + # Pinned, and kept in sync with the wails/v2 version in go.mod. The CLI + # generates the bridge bindings and drives the build, so letting it + # float means a future release can change the output — or drift from the + # library it generates against — with nothing in this repository + # changing. The release workflow pins the same version. + run: go install github.com/wailsapp/wails/v2/cmd/wails@v2.15.0 + + - name: Build + shell: bash + run: | + TAGS="" + if [ "$RUNNER_OS" = "Linux" ]; then TAGS="-tags webkit2_41"; fi + wails build -platform ${{ matrix.platform }} $TAGS + - name: Vet & test shell: bash run: | @@ -36,19 +83,149 @@ jobs: go vet $TAGS ./... go test $TAGS -race -count=1 ./... - frontend: - name: Frontend (check + build) - runs-on: ubuntu-latest + quality: + name: Quality (lint, types, tidy) + runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup Go + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version-file: go.mod + + - name: Setup Node.js + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "20" cache: npm cache-dependency-path: frontend/package-lock.json - - run: npm ci + + - name: Install Linux dependencies + run: sudo apt-get update && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev pkg-config + + - name: Install frontend deps + run: npm ci working-directory: frontend - - run: npx svelte-check --tsconfig ./tsconfig.json --fail-on-warnings + + - name: Svelte type check + run: npx svelte-check --tsconfig ./tsconfig.json --fail-on-warnings working-directory: frontend - - run: npm run build + + # main.go carries `//go:embed all:frontend/dist`, and frontend/dist is + # gitignored, so anything that compiles the main package fails with + # "pattern all:frontend/dist: no matching files found" before it analyses a + # line. staticcheck stops outright; govulncheck is worse — it carries on + # and silently reports on the subpackages alone, so main would look clean + # because it was never looked at. A placeholder rather than a real frontend + # build: neither tool inspects the bytes the binary embeds, and the build + # job already compiles the real thing on all three platforms. + - name: Placeholder for the embedded frontend + run: | + mkdir -p frontend/dist + echo '' > frontend/dist/index.html + + - name: Staticcheck + # Catches what go vet does not: dead stores, misused stdlib contracts, + # simplifications that hide intent. + # + # Pinned, unlike govulncheck below. A linter that floats can fail a + # commit that changed nothing, because a newly added check fired — the + # finding may well be real, but it should arrive in its own deliberate + # bump, not as a surprise on someone else's pull request. Dependabot + # does not track versions inside a `run:` step, so this is bumped by + # hand. + run: | + go install honnef.co/go/tools/cmd/staticcheck@v0.8.1 + staticcheck -tags webkit2_41 ./... + + - name: go.mod is tidy + # A stale go.mod/go.sum means the dependency set that CI resolves is not + # the one recorded in the repo, so every other check here is verifying + # something slightly different from what a release builds. + run: | + go mod tidy + git diff --exit-code go.mod go.sum + + security: + name: Security audit + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup Go + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version-file: go.mod + + - name: Setup Node.js + uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: "20" + cache: npm + cache-dependency-path: frontend/package-lock.json + + # main.go carries `//go:embed all:frontend/dist`, and frontend/dist is + # gitignored, so anything that compiles the main package fails with + # "pattern all:frontend/dist: no matching files found" before it analyses a + # line. staticcheck stops outright; govulncheck is worse — it carries on + # and silently reports on the subpackages alone, so main would look clean + # because it was never looked at. A placeholder rather than a real frontend + # build: neither tool inspects the bytes the binary embeds, and the build + # job already compiles the real thing on all three platforms. + - name: Placeholder for the embedded frontend + run: | + mkdir -p frontend/dist + echo '' > frontend/dist/index.html + + # govulncheck's analysis is only as complete as the packages it manages to + # load, and it does not fail when one of them does not build — it reports + # on the rest and prints a clean bill of health. On Linux the Wails + # packages need cgo against GTK/WebKit and the webkit2_41 tag, so without + # these the main package silently drops out of the scan. This build is the + # tripwire: it fails loudly if the toolchain cannot compile what the next + # step is supposed to analyse. + - name: Install Linux dependencies + run: sudo apt-get update && sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev pkg-config + + - name: Confirm the tree builds before scanning it + run: go build -tags webkit2_41 ./... + + - name: Go vulnerability check + # Reports only vulnerabilities in code paths the binary actually calls, + # standard library included — which is how the Go 1.25 -> 1.26 toolchain + # bump was found to be a security fix and not just housekeeping. + # + # Deliberately @latest, unlike staticcheck: the point of this step is to + # know about advisories published since the last commit, and an old + # scanner reports an old world. A new finding here means a real new + # advisory, not a new opinion about existing code. + run: | + go install golang.org/x/vuln/cmd/govulncheck@latest + govulncheck -tags webkit2_41 ./... + + - name: npm audit (production dependencies) + # --omit=dev because the Vite/esbuild advisories affect the developer + # machine during `wails dev`, not the shipped binary; they are tracked + # separately and must not block a release. No `|| true` here: a swallowed + # exit code turns this step into decoration. + run: npm audit --omit=dev --audit-level=high working-directory: frontend + + # Blocks a pull request that introduces a dependency carrying a known + # advisory. govulncheck cannot do this: it reports on what is already merged. + dependency-review: + name: Dependency review + runs-on: ubuntu-24.04 + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 + with: + fail-on-severity: high diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..9f77d73 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,88 @@ +name: CodeQL + +# Static analysis of the code itself, which nothing else here does: go vet and +# staticcheck look for mistakes, govulncheck and npm audit look for known +# vulnerable dependencies, and none of them go looking for an exploitable +# pattern in code we wrote. The weekly run matters as much as the per-push one — +# a query added to CodeQL after a commit lands would otherwise never see it. + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '17 4 * * 1' + +permissions: + contents: read + +concurrency: + group: codeql-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-24.04 + permissions: + # Only this job may write findings; everything else stays read-only. + security-events: write + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + language: [go, javascript-typescript] + + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Setup Go + if: matrix.language == 'go' + uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 + with: + go-version-file: go.mod + + - name: Install Linux dependencies + if: matrix.language == 'go' + run: | + sudo apt-get update + sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev pkg-config + + - name: Initialize CodeQL + uses: github/codeql-action/init@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 + with: + languages: ${{ matrix.language }} + queries: security-and-quality + + # main.go carries `//go:embed all:frontend/dist`, and frontend/dist is + # produced by the frontend build and gitignored — so a plain `go build` + # fails with "pattern all:frontend/dist: no matching files found" before a + # single query runs. + # + # A placeholder rather than a real frontend build: CodeQL analyses the Go + # code, not the bytes the binary embeds, so `npm ci && npm run build` would + # cost minutes to produce something no query looks at. The + # javascript-typescript leg analyses the frontend SOURCE, which is what + # matters there. + - name: Placeholder for the embedded frontend + if: matrix.language == 'go' + run: | + mkdir -p frontend/dist + echo '' > frontend/dist/index.html + + # The Go analysis needs a real build. Autobuild would not know about the + # webkit2_41 tag, and would analyse a subset of the tree without saying so. + - name: Build Go + if: matrix.language == 'go' + run: go build -tags webkit2_41 ./... + + - name: Perform CodeQL analysis + uses: github/codeql-action/analyze@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 + with: + category: /language:${{ matrix.language }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8461403..9c121b9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,11 +29,13 @@ jobs: name: Windows (amd64) runs-on: windows-latest steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "20" cache: npm @@ -72,7 +74,7 @@ jobs: cp build/bin/SyslogStudio.exe SyslogStudio-windows-amd64.exe mv build/bin/*installer*.exe SyslogStudio-windows-amd64-setup.exe powershell -Command "Compress-Archive -Path build/bin/SyslogStudio.exe -DestinationPath SyslogStudio-windows-amd64.zip" - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: windows-amd64 path: | @@ -84,11 +86,13 @@ jobs: name: macOS (universal) runs-on: macos-latest steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "20" cache: npm @@ -122,7 +126,7 @@ jobs: ln -s /Applications dmg-staging/Applications hdiutil create -volname "SyslogStudio" -srcfolder dmg-staging -ov -format UDZO \ "SyslogStudio-macos-universal.dmg" - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: macos-universal path: | @@ -133,11 +137,13 @@ jobs: name: Linux (amd64) runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod - - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "20" cache: npm @@ -177,7 +183,7 @@ jobs: Depends: libgtk-3-0, libwebkit2gtk-4.1-0 EOF dpkg-deb --build pkg "SyslogStudio-linux-amd64.deb" - - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: linux-amd64 path: | @@ -191,12 +197,18 @@ jobs: runs-on: ubuntu-latest permissions: contents: write + # Build provenance: id-token to get the OIDC token that proves the + # attestation came from this workflow run, attestations to record it. + id-token: write + attestations: write steps: - - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 - - uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version-file: go.mod - - uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: artifacts merge-multiple: true @@ -219,10 +231,31 @@ jobs: fi go run ./tools/updatersign sign artifacts/SyslogStudio-checksums.txt test -s artifacts/SyslogStudio-checksums.txt.sig + # Signed, verifiable provenance for every published asset: which workflow, + # which commit, which runner produced these exact bytes. It answers a + # question the Ed25519 manifest signature does not — that signature proves + # the checksums were signed by the holder of the release key, not that the + # binaries were built from this repository by this workflow. + # + # Anyone can check a download without trusting this repo's tooling: + # gh attestation verify SyslogStudio-windows-amd64.exe --repo Wasabules/SyslogStudio + - name: Attest build provenance + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 + with: + subject-path: | + artifacts/SyslogStudio-windows-amd64.exe + artifacts/SyslogStudio-windows-amd64-setup.exe + artifacts/SyslogStudio-windows-amd64.zip + artifacts/SyslogStudio-macos-universal.dmg + artifacts/SyslogStudio-macos-universal.zip + artifacts/SyslogStudio-linux-amd64 + artifacts/SyslogStudio-linux-amd64.deb + artifacts/SyslogStudio-linux-amd64.tar.gz + - name: List release assets run: ls -lh artifacts/ - name: Create GitHub Release - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 + uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 with: generate_release_notes: true files: artifacts/* diff --git a/internal/syslog/framing_test.go b/internal/syslog/framing_test.go index c3a0ed9..eb56539 100644 --- a/internal/syslog/framing_test.go +++ b/internal/syslog/framing_test.go @@ -36,9 +36,9 @@ func eq(t *testing.T, got, want []string) { func TestFraming_OctetCounting_Single(t *testing.T) { msg := "<34>1 2003-10-11T22:14:15.003Z host app - - - hello" - input := "51 " + msg // note: length must match msg byte length - // Recompute the correct length rather than hardcoding. - input = itoa(len(msg)) + " " + msg + // The octet count must be the byte length of msg, so compute it rather + // than hardcoding a number that silently rots when msg is edited. + input := itoa(len(msg)) + " " + msg eq(t, scanAll(t, input), []string{msg}) }