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
25 changes: 25 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
version: 2
updates:
# VS Code extension JavaScript/TypeScript toolchain.
- package-ecosystem: npm
directory: /vscode-extension
schedule:
interval: weekly
open-pull-requests-limit: 5
groups:
dev-dependencies:
dependency-type: development

# Python build-time deps used by the keyword-index generator.
- package-ecosystem: pip
directory: /scripts
schedule:
interval: weekly
open-pull-requests-limit: 3

# CI actions — keep SHA pins fresh as upstream tags advance.
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
34 changes: 19 additions & 15 deletions .github/workflows/build-vsix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,21 @@ on:
branches: [main]
workflow_dispatch:

# Default least-privilege token scope; jobs that need more elevate explicitly.
permissions:
contents: read

jobs:
build-index:
runs-on: ubuntu-latest
steps:
- name: Checkout (with submodule)
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
submodules: recursive

- name: Setup Python
uses: actions/setup-python@v6
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: '3.12'
cache: pip
Expand All @@ -39,7 +43,7 @@ jobs:
--compact vscode-extension/data/keyword_index_compact.json

- name: Upload keyword index
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: keyword-index
path: vscode-extension/data/keyword_index_compact.json
Expand All @@ -56,17 +60,17 @@ jobs:

steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: '24'
cache: npm
cache-dependency-path: vscode-extension/package-lock.json

- name: Download freshly built keyword index
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: keyword-index
path: vscode-extension/data
Expand All @@ -81,18 +85,18 @@ jobs:
run: npm run compile

- name: Package VSIX
run: npx --yes @vscode/vsce package
run: npx --yes @vscode/vsce@3.9.1 package

- name: Upload VSIX artifact
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: opm-flow-editor-support-vsix
path: vscode-extension/opm-flow-editor-support-*.vsix
if-no-files-found: error

- name: Attach VSIX to release
if: startsWith(github.ref, 'refs/tags/v')
uses: softprops/action-gh-release@v3
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3
with:
files: vscode-extension/opm-flow-editor-support-*.vsix

Expand All @@ -102,20 +106,20 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: '24'

- name: Download VSIX
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: opm-flow-editor-support-vsix
path: .

- name: Publish to VS Code Marketplace
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
run: npx --yes @vscode/vsce publish --packagePath opm-flow-editor-support-*.vsix --pat "$VSCE_PAT"
run: npx --yes @vscode/vsce@3.9.1 publish --packagePath opm-flow-editor-support-*.vsix --pat "$VSCE_PAT"

# Disabled until Open VSX account + OVSX_PAT secret are set up.
# To re-enable: change `if: false` back to `if: startsWith(github.ref, 'refs/tags/v')`.
Expand All @@ -125,17 +129,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Setup Node.js
uses: actions/setup-node@v6
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: '24'

- name: Download VSIX
uses: actions/download-artifact@v8
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: opm-flow-editor-support-vsix
path: .

- name: Publish to Open VSX
env:
OVSX_PAT: ${{ secrets.OVSX_PAT }}
run: npx --yes ovsx publish opm-flow-editor-support-*.vsix -p "$OVSX_PAT"
run: npx --yes ovsx@0.10.12 publish opm-flow-editor-support-*.vsix -p "$OVSX_PAT"
42 changes: 42 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Security Policy

## Supported versions

Only the latest released version of the OPM Flow Editor Support VS Code
extension receives security updates. Older versions are not patched.

## Reporting a vulnerability

If you believe you have found a security vulnerability in this extension,
please report it privately rather than opening a public issue.

Use GitHub's
[private vulnerability reporting](https://github.com/OPM/opm-flow-editor-support/security/advisories/new)
to route the report directly to the maintainers. Please include:

- A description of the issue and its impact.
- Steps to reproduce, ideally including a minimal deck file or
configuration that triggers the behaviour.
- The extension version (`Extensions: Show Installed Extensions` in
VS Code) and your VS Code version.

You should receive an acknowledgement within a few business days. We will
work with you on a fix and coordinate a disclosure timeline; please give
us a reasonable window to release a patched version before any public
disclosure.

## Scope

In scope:

- The published `magne-sjaastad.opm-flow-editor-support` VS Code extension.
- The build / packaging pipeline in `.github/workflows/build-vsix.yml`.
- Helper scripts in `scripts/` that produce the bundled keyword index.

Out of scope:

- Vulnerabilities in OPM Flow itself, the OPM reference manual, or other
upstream OPM projects — please report those to the relevant
[OPM repository](https://github.com/OPM).
- Issues that require an already-compromised developer machine or an
attacker-controlled VS Code installation.
20 changes: 15 additions & 5 deletions vscode-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,12 @@ function resolveKeyword(index: KeywordIndex, kw: string): KeywordEntry | undefin
// ---------------------------------------------------------------------------

function escHtml(s: string): string {
return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
return s
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}

function paramTypeLabel(p: Parameter): string {
Expand Down Expand Up @@ -327,7 +332,7 @@ function buildDocsHtml(
? ' class="highlight"' : '';
const dataRecord = p.record !== undefined
? ` data-record="${escHtml(String(p.record))}"` : '';
return `<tr data-param-index="${escHtml(String(p.index))}"${dataRecord}${hl}><td>${p.index}</td><td class="name"><code>${escHtml(p.name)}</code></td><td>${escHtml(p.description)}</td>${typeCell}${unitCells}${defaultCell}</tr>`;
return `<tr data-param-index="${escHtml(String(p.index))}"${dataRecord}${hl}><td>${escHtml(String(p.index))}</td><td class="name"><code>${escHtml(p.name)}</code></td><td>${escHtml(p.description)}</td>${typeCell}${unitCells}${defaultCell}</tr>`;
};

const tableHead = `<thead><tr><th>No.</th><th class="name">Name</th><th>Description</th>${typeCol}${unitCols}${defaultCol}</tr></thead>`;
Expand Down Expand Up @@ -422,7 +427,10 @@ class DocsViewProvider implements vscode.WebviewViewProvider {

resolveWebviewView(view: vscode.WebviewView): void {
this._view = view;
view.webview.options = { enableScripts: true };
// The docs panel renders only inline HTML/CSS/JS that we build here, so
// it never needs to load files from disk. Drop `localResourceRoots` to
// an empty list to deny the webview any filesystem access.
view.webview.options = { enableScripts: true, localResourceRoots: [] };
view.webview.html = buildDocsHtml(null, null, getDocColumns());
this._currentEntry = undefined;
this._currentParam = undefined;
Expand Down Expand Up @@ -469,7 +477,9 @@ function buildKeywordHover(
isExcluded?: boolean,
): vscode.MarkdownString {
const md = new vscode.MarkdownString();
md.isTrusted = true;
// `supportHtml` is enough for the inline <span style="..."> notices below.
// `isTrusted` would additionally permit `command:` links to execute, which
// these hovers never use — keep it off as defense in depth.
md.supportHtml = true;

if (
Expand Down Expand Up @@ -499,7 +509,7 @@ function buildKeywordHover(

function buildParameterHover(entry: KeywordEntry, param: Parameter): vscode.MarkdownString {
const md = new vscode.MarkdownString();
md.isTrusted = true;
// No HTML or command links needed here — pure markdown is sufficient.
md.appendMarkdown(`**\`${entry.name}\` — parameter ${param.index}: \`${param.name}\`**\n\n`);
md.appendMarkdown(`${param.description}\n\n`);
const cols = getDocColumns();
Expand Down