ci: address code scanning scorecard alerts (#4275)

This commit is contained in:
Huang Xin
2026-05-23 02:20:10 +08:00
committed by GitHub
parent 0564b4dd48
commit 8a19c686cb
6 changed files with 57 additions and 14 deletions
+15 -10
View File
@@ -15,10 +15,12 @@ concurrency:
permissions:
contents: read
packages: write
jobs:
build:
permissions:
contents: read
packages: write
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
@@ -42,10 +44,10 @@ jobs:
submodules: recursive
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Log in to GHCR
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -53,13 +55,13 @@ jobs:
- name: Docker meta (for labels)
id: meta
uses: docker/metadata-action@v5
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: ghcr.io/${{ github.repository_owner }}/readest
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
with:
context: .
file: ./Dockerfile
@@ -87,6 +89,9 @@ jobs:
merge:
needs: build
permissions:
contents: read
packages: write
runs-on: ubuntu-latest
steps:
- name: Download digests
@@ -97,10 +102,10 @@ jobs:
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
- name: Log in to GHCR
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -117,7 +122,7 @@ jobs:
- name: Log in to Docker Hub
if: steps.dockerhub.outputs.enabled == 'true'
uses: docker/login-action@v3
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -125,7 +130,7 @@ jobs:
- name: Extract image metadata (GHCR only)
id: meta-ghcr
if: steps.dockerhub.outputs.enabled != 'true'
uses: docker/metadata-action@v5
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: ghcr.io/${{ github.repository_owner }}/readest
tags: |
@@ -137,7 +142,7 @@ jobs:
- name: Extract image metadata (GHCR + Docker Hub)
id: meta-all
if: steps.dockerhub.outputs.enabled == 'true'
uses: docker/metadata-action@v5
uses: docker/metadata-action@c299e40c65443455700f0fdfc63efafe5b349051 # v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/readest
+1 -2
View File
@@ -10,7 +10,6 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
@@ -18,7 +17,7 @@ jobs:
- uses: amondnet/vercel-action@de09aeac2ace6599ec9b11ef87558759a496bac4 # v42
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
github-comment: false
vercel-args: '--prod'
vercel-org-id: ${{ secrets.ORG_ID}}
vercel-project-id: ${{ secrets.PROJECT_ID}}
+1
View File
@@ -235,6 +235,7 @@
"cpx2": "^8.0.0",
"daisyui": "^4.12.24",
"dotenv-cli": "^7.4.4",
"fast-check": "^4.8.0",
"i18next-scanner": "^4.6.0",
"jsdom": "^28.1.0",
"mkdirp": "^3.0.1",
@@ -1,3 +1,4 @@
import fc from 'fast-check';
import { describe, it, expect } from 'vitest';
import { makeSafeFilename } from '../../utils/misc';
@@ -53,6 +54,11 @@ describe('makeSafeFilename', () => {
expect(makeSafeFilename('LPT9')).toBe('LPT9_');
});
it('should handle reserved names after trimming whitespace', () => {
expect(makeSafeFilename(' CON ')).toBe('CON_');
expect(makeSafeFilename(' prn ')).toBe('prn_');
});
it('should not affect reserved names with extensions', () => {
// Reserved names only apply to the base name without extension
const result = makeSafeFilename('CON.txt');
@@ -375,4 +381,20 @@ describe('makeSafeFilename', () => {
expect(result).toBe('https___example.com_book.pdf');
});
});
describe('Property checks', () => {
it('should keep sanitized filenames bounded, safe, trimmed, and stable', () => {
fc.assert(
fc.property(fc.string({ maxLength: 1000 }), (filename) => {
const result = makeSafeFilename(filename);
expect(new TextEncoder().encode(result).length).toBeLessThanOrEqual(250);
expect(result).not.toMatch(/[<>:%#"\/\\|?*\x00-\x1F]/);
expect(result).toBe(result.trim());
expect(makeSafeFilename(result)).toBe(result);
}),
{ numRuns: 200 },
);
});
});
});
+2 -2
View File
@@ -15,7 +15,7 @@ export const makeSafeFilename = (filename: string, replacement = '_') => {
// Unsafe to use filename including file extensions over 255 bytes on Android
const maxFilenameBytes = 250;
let safeName = filename.replace(unsafeCharacters, replacement);
let safeName = filename.replace(unsafeCharacters, replacement).trim();
if (reservedFilenames.test(safeName)) {
safeName = `${safeName}${replacement}`;
@@ -29,7 +29,7 @@ export const makeSafeFilename = (filename: string, replacement = '_') => {
utf8Bytes = encoder.encode(safeName);
}
return safeName.trim();
return safeName;
};
export const getLocale = () => {
+16
View File
@@ -508,6 +508,9 @@ importers:
dotenv-cli:
specifier: ^7.4.4
version: 7.4.4
fast-check:
specifier: ^4.8.0
version: 4.8.0
i18next-scanner:
specifier: ^4.6.0
version: 4.6.0(typescript@5.9.3)
@@ -5542,6 +5545,10 @@ packages:
engines: {node: '>= 10.17.0'}
hasBin: true
fast-check@4.8.0:
resolution: {integrity: sha512-GOJ158CUMnN6cSahsv4+ExARvIDuzzinFjkp0E9WtiBa5zcVeLozVkWaE4IzFcc+Y48Wp1EDlUZsXRyAztQcSg==}
engines: {node: '>=12.17.0'}
fast-deep-equal@2.0.1:
resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==}
@@ -7300,6 +7307,9 @@ packages:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
pure-rand@8.4.0:
resolution: {integrity: sha512-IoM8YF/jY0hiugFo/wOWqfmarlE6J0wc6fDK1PhftMk7MGhVZl88sZimmqBBFomLOCSmcCCpsfj7wXASCpvK9A==}
qs@6.15.1:
resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==}
engines: {node: '>=0.6'}
@@ -14300,6 +14310,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
fast-check@4.8.0:
dependencies:
pure-rand: 8.4.0
fast-deep-equal@2.0.1: {}
fast-deep-equal@3.1.3: {}
@@ -16422,6 +16436,8 @@ snapshots:
punycode@2.3.1: {}
pure-rand@8.4.0: {}
qs@6.15.1:
dependencies:
side-channel: 1.1.0