From b21d7a892e04d5efc1ec9c31dab8b3145b6113bb Mon Sep 17 00:00:00 2001 From: Ihor Kalnytskyi Date: Sun, 26 Jul 2026 02:46:08 +0300 Subject: [PATCH] Add URI-unsafe connection parameters support PostgreSQL usernames, passwords and database names may contain characters reserved by URI syntax. Percent-encode these values when constructing the connection URI so clients can parse it correctly. --- .github/workflows/ci.yml | 10 +++++----- action.yml | 6 ++++-- tests/test_action.py | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6dd8a9d4..a24be5e1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -93,9 +93,9 @@ jobs: - name: Run setup-postgres uses: ./ with: - username: yoda - password: GrandMaster - database: jedi_order + username: user:@/ n#m+e + password: p@ss:/ word?# + database: d@ta /#bas?:e port: 34837 postgres-version: ${{ matrix.postgres-version }} ssl: true @@ -118,8 +118,8 @@ jobs: CONNECTION_URI: ${{ steps.postgres.outputs.connection-uri }} SERVICE_NAME: ${{ steps.postgres.outputs.service-name }} CERTIFICATE_PATH: ${{ steps.postgres.outputs.certificate-path }} - EXPECTED_CONNECTION_URI: postgresql://yoda:GrandMaster@localhost:34837/jedi_order?sslmode=verify-ca&sslrootcert=${{ steps.postgres.outputs.certificate-path }} - EXPECTED_SERVICE_NAME: yoda + EXPECTED_CONNECTION_URI: "postgresql://user%3A%40%2F%20n%23m%2Be:p%40ss%3A%2F%20word%3F%23@localhost:34837/d%40ta%20%2F%23bas%3F%3Ae?sslmode=verify-ca&sslrootcert=${{ steps.postgres.outputs.certificate-path }}" + EXPECTED_SERVICE_NAME: "user:@/ n#m+e" EXPECTED_SERVER_VERSION: ${{ matrix.postgres-version }} EXPECTED_SSL: true diff --git a/action.yml b/action.yml index 19538232..6b0bad57 100644 --- a/action.yml +++ b/action.yml @@ -87,7 +87,6 @@ runs: # download failures. for attempt in 1 2 3; do if choco install postgresql$INPUT_POSTGRES_VERSION \ - --params "/Password:$INPUT_PASSWORD" \ --ia "--enable-components server,commandlinetools --extract-only 1" \ --no-progress; then break @@ -249,7 +248,10 @@ runs: - name: Set action outputs run: | - CONNECTION_URI="postgresql://$INPUT_USERNAME:$INPUT_PASSWORD@localhost:$INPUT_PORT/$INPUT_DATABASE" + USERNAME_ENCODED=$(jq -rn --arg s "$INPUT_USERNAME" '$s|@uri') + PASSWORD_ENCODED=$(jq -rn --arg s "$INPUT_PASSWORD" '$s|@uri') + DATABASE_ENCODED=$(jq -rn --arg s "$INPUT_DATABASE" '$s|@uri') + CONNECTION_URI="postgresql://$USERNAME_ENCODED:$PASSWORD_ENCODED@localhost:$INPUT_PORT/$DATABASE_ENCODED" CERTIFICATE_PATH="$RUNNER_TEMP/pgdata/server.crt" if [ "$INPUT_SSL" = "true" ]; then diff --git a/tests/test_action.py b/tests/test_action.py index 3865ed15..92a3f0ca 100644 --- a/tests/test_action.py +++ b/tests/test_action.py @@ -61,7 +61,7 @@ def connection( if request.param == "uri": return connection_factory(connection_uri) elif request.param == "kv-string": - return connection_factory(f"service={service_name}") + return connection_factory(psycopg.conninfo.make_conninfo(service=service_name)) raise RuntimeError("f{request.param}: unknown value")