Skip to content
Merged
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
12 changes: 9 additions & 3 deletions .github/osv-scanner.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Advisories this repository has read and settled, for OSV-Scanner.
#
# THE SCANNER READS THIS FILE FOR THE FILES IN THIS FOLDER ONLY. It does not carry it into
# subfolders - the scanner's own documentation for the pinned v2.6.0 says so, and it was measured on
# 2026-10-16: the same entry one folder down left the advisory in the report. That is on purpose
# subfolders - the scanner's own documentation for v2.6.0 says so, and it was measured with v2.6.0
# on 2026-10-16 and again with the pinned v2.7.0 on 2026-10-26: the same entry one folder up from
# the list left both advisories in the report, and in this folder it filtered them. That is on purpose
# here, because the canary files in osv-scanner/ must keep coming back vulnerable. The one file
# .github/workflows/osv-scanner.yml scans in this folder is semgrep.installed.txt, which it writes
# from what pip would install for semgrep, so every entry below is about a package semgrep brings.
Expand All @@ -15,4 +16,9 @@
[[IgnoredVulns]]
id = "GHSA-84m7-p3x7-pcfv"
ignoreUntil = 2026-11-16
reason = "mcp 1.29.0 is here only because semgrep requires it, and CI runs semgrep as semgrep scan. The advisory is about an MCP server over Streamable HTTP, and nothing in this repository serves MCP. The fix is mcp 1.30.0, but semgrep 1.180.0 and 1.181.0 both require mcp==1.29.0 exactly, so pip cannot install it. Remove this entry once a semgrep release allows mcp 1.30.0 or later."
reason = "mcp 1.29.0 is here only because semgrep requires it, and CI runs semgrep as semgrep scan. The advisory is about an MCP server over Streamable HTTP, and nothing in this repository serves MCP. The fix is mcp 1.30.0, but every semgrep release from 1.180.0 to 1.182.1 requires mcp==1.29.0 exactly (read on the package index on 2026-10-26), so pip cannot install it. Remove this entry once a semgrep release allows mcp 1.30.0 or later."

[[IgnoredVulns]]
id = "GHSA-xcq7-p3pf-p88h"
ignoreUntil = 2026-11-16
reason = "opentelemetry-api 1.37.0 is here only because semgrep requires opentelemetry-api~=1.37.0, which excludes every release from 1.38 up. The advisory is a denial of service through a slow regular expression in TraceState.from_header, reached when server instrumentation passes an incoming tracestate header to the propagator. CI runs semgrep as a one-off command line scan with metrics off (.github/workflows/security.yml, the semgrep scan step), so it serves no HTTP and receives no such header. The fix is opentelemetry-api 1.45.1, which pip cannot install next to the pinned semgrep. Remove this entry once a semgrep release allows opentelemetry-api 1.45.1 or later."
10 changes: 6 additions & 4 deletions .github/osv-scanner/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
# the `docker` entry in .github/dependabot.yml proposes the next release of the scanner here,
# tag and digest together, after the same seven days of cooldown as everything else.
#
# v2.6.0 rather than v2.7.0, which was the newest release on 2026-10-14 but two days old - the
# cooldown above applied to the first pin as well. The digest is the multi-architecture index,
# read from ghcr.io the same day. The image's entry point is the scanner itself.
FROM ghcr.io/google/osv-scanner:v2.6.0@sha256:afd838850ac1a0fcc15ff4a041dc9ba11123c3f0d2666217a5f0fcf9222b55fa
# v2.7.0 is the newest release on 2026-10-26, published on 2026-10-12, so it is past the cooldown
# above. The first pin was v2.6.0 because v2.7.0 was two days old on 2026-10-14 and the cooldown
# applied to that pin as well. The digest is the multi-architecture index, read from ghcr.io on
# 2026-10-26, and the same read on v2.6.0 returned the digest that was pinned here before, which
# is how the reading was checked. The image's entry point is the scanner itself.
FROM ghcr.io/google/osv-scanner:v2.7.0@sha256:4f3b7e2c64b9d38a5febc5a7e4a3dfef1d1362f726dea7a2ef4762b46469fcd0
47 changes: 29 additions & 18 deletions .github/requirements-semgrep.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,41 @@
# release turning a green branch red on a commit that touched nothing teaches everybody to
# ignore the check.
#
# THE GATE'S NUMBERS ARE MEASURED WITH THE VERSION BELOW. Measured again on 2026-10-14, when the
# version moved from 1.178.0 to 1.180.0, the newest stable release on the package index that day,
# with the pull request that brought snapshots to the window. That pull request's own Semgrep run,
# on the merge of commit c8ea3cb into main with `--config p/default`: semgrep ran 374 rules over
# 399 files and reported zero findings, and the gate read zero errors at level error and 419 rules.
# The two rule counts are one run read two ways - 374 is semgrep's own summary, 419 the timing
# list in the report, which is what the gate counts. The run on the commit before, d39889d, gave
# the same numbers. Before them the numbers here were from 1.177.0 on 2026-09-22 (131 rules, 301
# files), and 1.178.0 was never measured. Moving this line means measuring again rather than
# assuming the report will look the same.
# THE GATE'S NUMBERS ARE MEASURED WITH THE VERSION BELOW. Measured again on 2026-10-26, when the
# version moved from 1.180.0 to 1.181.0. The run is the Semgrep job of Dependabot's own pull request
# for that bump (run 40335089268, on the merge of its branch into main with `--config p/default`):
# the gate read zero blocking findings, zero scan errors, 680 files and 424 rules, and semgrep's own
# summary said it loaded 1074 code rules, ran 379 of them and found nothing. The two rule counts
# are one run read two ways - 379 is semgrep's own summary, 424 the timing list in the report,
# which is what the gate counts. For 1.180.0 on 2026-10-14 the same pair was 374 and 419, over 399
# files. Before that the numbers here were from 1.177.0 on 2026-09-22 (131 rules, 301 files), and
# 1.178.0 was never measured. Moving this line means measuring again rather than assuming the
# report will look the same.
#
# 399 OF 743 FILES, AND THAT IS NOT A FAULT. Semgrep's own default ignore patterns exclude
# tests/, which is 336 of this repository's files, one picture is skipped for being over 1 MB, and
# the seven other pictures are not among the 399 either - that last part is the arithmetic of the
# count, not a line semgrep prints. So a healthy run of this tree reads src/, site/, .github/,
# packaging/ and the root - about four hundred files - and a collapse to a handful is the shape of
# a scan that ran somewhere else. The gate prints the number on every run for exactly that reason.
# WHY 1.181.0 AND NOT THE NEWEST. 1.182.0 was uploaded on 2026-10-20 and 1.182.1 on 2026-10-22,
# both inside the seven days of cooldown .github/dependabot.yml asks for, and 1.181.0 (uploaded on
# 2026-10-14) is the release whose run is measured above. Choosing a newer one would mean pinning a
# version nobody has measured here. It would also not change the entries in osv-scanner.toml, because
# on 2026-10-26 the package index showed every release from 1.180.0 to 1.182.1 requiring the same
# mcp==1.29.0 and opentelemetry-api~=1.37.0.
#
# 680 OF 1081 FILES, AND THAT IS NOT A FAULT. Semgrep's own default ignore patterns exclude
# tests/, which is 393 of this repository's files on main at 845c8a4, and one picture is skipped
# for being over 1 MB. That leaves 688 and the scan read 680, so eight files are neither tests nor
# the oversized picture - the other pictures are what is left, but that is the arithmetic of the
# count and not a line semgrep prints. The same eight were left over on 2026-10-14, when the scan
# read 399 of 407 files outside tests/. The growth since then is 281 files added outside tests/,
# of which 221 are the language pages and strings in site/. So a healthy run of this tree reads
# src/, site/, .github/, packaging/ and the root - about seven hundred files today - and a collapse
# to a handful is the shape of a scan that ran somewhere else. The gate prints the number on every
# run for exactly that reason.
#
# Licence, read on 2026-09-22 from that version's own metadata rather than recalled, and read again
# on 2026-10-14 from 1.180.0's, which says the same. The
# on 2026-10-26 from 1.181.0's, which says the same. The
# package index reports `license_expression` as LGPL-2.1-or-later, with the older `license`
# field null and no licence classifier - which is the modern shape and worth saying, because a
# reader checking the field that used to hold this would find nothing and could conclude the
# licence was unstated. It analyses the source tree in CI and is never linked into anything this
# project ships, so it creates no distribution obligation - see THIRD-PARTY-NOTICES.md for what
# does.
semgrep==1.180.0
semgrep==1.181.0
4 changes: 2 additions & 2 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:
persist-credentials: false

- name: Initialise CodeQL
uses: github/codeql-action/init@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
uses: github/codeql-action/init@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
languages: ${{ matrix.language }}
# Nothing is compiled. build.yml already builds this product on a Windows runner on the
Expand All @@ -97,6 +97,6 @@ jobs:
queries: security-extended

- name: Analyse
uses: github/codeql-action/analyze@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
uses: github/codeql-action/analyze@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
category: /language:${{ matrix.language }}
4 changes: 2 additions & 2 deletions .github/workflows/osv-scanner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:

# The Python the Semgrep job uses. pip's answer depends on it - starlette, for one, asks for
# a different minimum from Python 3.14 on.
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: '3.14'

Expand Down Expand Up @@ -199,7 +199,7 @@ jobs:

# Its own category, so these alerts never replace CodeQL's and CodeQL's never replace these.
# An upload with no results is what closes an alert that a merged fix made obsolete.
- uses: github/codeql-action/upload-sarif@24c54180a607b1449ed407dd24f251e4e9147c8d # v4.38.3
- uses: github/codeql-action/upload-sarif@9b3254085494b55a0f7c4c2b3d2d52cc712ce370 # v4.39.1
with:
sarif_file: ${{ runner.temp }}/osv/osv.sarif
category: osv-scanner
4 changes: 2 additions & 2 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
# step inherits. The scanner reads this tree, including this file.
persist-credentials: false

- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: '3.14'

Expand Down Expand Up @@ -133,7 +133,7 @@ jobs:
comment-summary-in-pr: never
fail-on-severity: low

- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
with:
python-version: '3.14'

Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@
dependency on Roslyn, recorded in ADR-15. Nothing that ships carries it.
-->
<ItemGroup>
<PackageReference Include="Meziantou.Analyzer" Version="3.0.299">
<PackageReference Include="Meziantou.Analyzer" Version="3.0.313">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
12 changes: 6 additions & 6 deletions THIRD-PARTY-NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,13 @@ list should be able to tell at a glance which side of the line each one falls on

| Package | Licence | What it does |
|---|---|---|
| Microsoft.Windows.CsWin32 0.3.298 | MIT | Generates the P/Invoke declarations at build time. Marked `PrivateAssets="all"`, so the generator itself does not ship - the code it generates is compiled into ours |
| Meziantou.Analyzer 3.0.138 | MIT, (c) Gérald Barré | Extra analyser rules |
| xunit 2.9.3, xunit.runner.visualstudio 3.1.4 | Apache-2.0 | Test framework |
| Microsoft.NET.Test.Sdk 17.14.1 | MIT | Test host |
| Microsoft.Windows.CsWin32 0.3.363 | MIT | Generates the P/Invoke declarations at build time. Marked `PrivateAssets="all"`, so the generator itself does not ship - the code it generates is compiled into ours |
| Meziantou.Analyzer 3.0.313 | MIT, (c) Gérald Barré | Extra analyser rules |
| xunit.v3.mtp-off 4.0.2, xunit.runner.visualstudio 4.0.1 | Apache-2.0 | Test framework |
| Microsoft.NET.Test.Sdk 18.11.0 | MIT | Test host |
| coverlet.collector 6.0.4 | MIT | Coverage collection |
| CsCheck 4.7.0 | Apache-2.0 | Property-based testing |
| Microsoft.Windows.SDK.Win32Metadata 70.0.11-preview | Windows SDK licence terms | The machine-readable description of the Win32 API that CsWin32 reads to generate from. Arrives as its dependency rather than being asked for |
| CsCheck 4.9.1 | Apache-2.0 | Property-based testing |
| Microsoft.Windows.SDK.Win32Metadata 71.0.30-preview | Windows SDK licence terms | The machine-readable description of the Win32 API that CsWin32 reads to generate from. Arrives as its dependency rather than being asked for |
| Microsoft.Windows.WDK.Win32Metadata 0.13.25-experimental | Windows SDK licence terms | The same thing for the driver-facing half of the API |
| Microsoft.Windows.SDK.Win32Docs 0.1.42-alpha | Windows SDK licence terms | The documentation text CsWin32 copies into the generated declarations, so that hovering a generated method shows what Microsoft says about it |

Expand Down
11 changes: 11 additions & 0 deletions site/assets/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,17 @@ html:lang(vi) { --lh-body: 1.7; --lh-tight: 1.3; }
*/
html:lang(ko) { word-break: keep-all; }

/*
Japanese has no spaces, so by default a line may break between any two characters, and at 375 px
the headlines split inside words (measured on the home page: the verb for "search" and the word
for "preview" were each cut after their first character). auto-phrase breaks between phrases instead. It is supported by Chrome and Edge from 119 and not
by Firefox, and Safari has it only in its preview (MDN compatibility data, read 2026-10-26). A
browser without it drops the declaration and keeps the default, so for them nothing changes. It
is limited to Japanese because that is the language it was measured on: Chrome would also apply it
to Korean, which already breaks at its spaces through the rule above.
*/
html:lang(ja) { word-break: auto-phrase; }

@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
}
Loading
Loading