From 94203b2c8b88d915b44fac573b08f7596e9e386e Mon Sep 17 00:00:00 2001 From: 35C4n0r <70096901+35C4n0r@users.noreply.github.com> Date: Mon, 1 Jun 2026 17:48:19 +0530 Subject: [PATCH] fix(coder/modules/dotfiles): allow tilde in DOTFILES_URI shell validation (#904) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/coder/registry/issues/762 ## Problem The shell-side URI validation regex in `run.sh` did not include `~` in the allowed character set. URLs containing tilde paths (common in Bitbucket Server personal repositories, e.g. `ssh://git@bitbucket.example.org:7999/~user/repo.git`) were rejected at runtime with `ERROR: DOTFILES_URI contains invalid characters`. The Terraform-side validations in `main.tf` already allowed `~`, so the inconsistency only surfaced when the script actually ran in a workspace. ## Changes - **`run.sh`**: Added `~` to the character class in the shell validation regex, making it consistent with the three Terraform regex patterns in `main.tf`. - **`main.test.ts`**: The "accepts valid git URL formats" test now also executes the rendered shell script and asserts that the shell-side validation does not reject any of the valid URLs. This closes the coverage gap that let the Terraform/shell inconsistency go undetected. > 🤖 Generated by Coder Agents --------- Authored-by: Jay Kumar --- registry/coder/modules/dotfiles/README.md | 12 ++++++------ registry/coder/modules/dotfiles/main.test.ts | 20 ++++++++++++++++++++ registry/coder/modules/dotfiles/run.sh | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/registry/coder/modules/dotfiles/README.md b/registry/coder/modules/dotfiles/README.md index 2cab271b..aea57e75 100644 --- a/registry/coder/modules/dotfiles/README.md +++ b/registry/coder/modules/dotfiles/README.md @@ -18,7 +18,7 @@ Under the hood, this module uses the [coder dotfiles](https://coder.com/docs/v2/ module "dotfiles" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/dotfiles/coder" - version = "1.4.1" + version = "1.4.2" agent_id = coder_agent.example.id } ``` @@ -31,7 +31,7 @@ module "dotfiles" { module "dotfiles" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/dotfiles/coder" - version = "1.4.1" + version = "1.4.2" agent_id = coder_agent.example.id } ``` @@ -42,7 +42,7 @@ module "dotfiles" { module "dotfiles" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/dotfiles/coder" - version = "1.4.1" + version = "1.4.2" agent_id = coder_agent.example.id user = "root" } @@ -54,14 +54,14 @@ module "dotfiles" { module "dotfiles" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/dotfiles/coder" - version = "1.4.1" + version = "1.4.2" agent_id = coder_agent.example.id } module "dotfiles-root" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/dotfiles/coder" - version = "1.4.1" + version = "1.4.2" agent_id = coder_agent.example.id user = "root" dotfiles_uri = module.dotfiles.dotfiles_uri @@ -90,7 +90,7 @@ You can set a default dotfiles repository for all users by setting the `default_ module "dotfiles" { count = data.coder_workspace.me.start_count source = "registry.coder.com/coder/dotfiles/coder" - version = "1.4.1" + version = "1.4.2" agent_id = coder_agent.example.id default_dotfiles_uri = "https://github.com/coder/dotfiles" } diff --git a/registry/coder/modules/dotfiles/main.test.ts b/registry/coder/modules/dotfiles/main.test.ts index 67e0f4a9..62aa15e1 100644 --- a/registry/coder/modules/dotfiles/main.test.ts +++ b/registry/coder/modules/dotfiles/main.test.ts @@ -1,9 +1,11 @@ import { describe, expect, it } from "bun:test"; import { + findResourceInstance, runTerraformApply, runTerraformInit, testRequiredVariables, } from "~test"; +import { readableStreamToText, spawn } from "bun"; describe("dotfiles", async () => { await runTerraformInit(import.meta.dir); @@ -34,6 +36,24 @@ describe("dotfiles", async () => { dotfiles_uri: url, }); expect(state.outputs.dotfiles_uri.value).toBe(url); + + // Run the rendered shell script to verify the shell-side URI + // validation also accepts the URL. The script will fail later + // (no coder binary available), but it must not fail at the + // URI validation step. + const instance = findResourceInstance(state, "coder_script"); + const proc = spawn(["bash", "-c", instance.script], { + stdout: "pipe", + stderr: "pipe", + }); + const stderr = await readableStreamToText(proc.stderr); + await proc.exited; + expect(stderr).not.toContain( + "ERROR: DOTFILES_URI contains invalid characters", + ); + expect(stderr).not.toContain( + "ERROR: DOTFILES_URI must be a valid repository URL", + ); } }); diff --git a/registry/coder/modules/dotfiles/run.sh b/registry/coder/modules/dotfiles/run.sh index f7f275f8..8ec7fa8d 100644 --- a/registry/coder/modules/dotfiles/run.sh +++ b/registry/coder/modules/dotfiles/run.sh @@ -9,7 +9,7 @@ DOTFILES_BRANCH="${DOTFILES_BRANCH}" # Validate DOTFILES_URI to prevent command injection (defense in depth) if [ -n "$DOTFILES_URI" ]; then # shellcheck disable=SC2250 - if [[ "$DOTFILES_URI" =~ [^a-zA-Z0-9._/:@-] ]]; then + if [[ "$DOTFILES_URI" =~ [^a-zA-Z0-9._/:@~-] ]]; then echo "ERROR: DOTFILES_URI contains invalid characters" >&2 exit 1 fi