Skip to content
Open
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: 10 additions & 2 deletions .github/workflows/bc.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
on: [push, pull_request]
name: Roave
permissions:
contents: read

jobs:
roave_bc_check:
name: BC Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit

- uses: actions/checkout@61b9e3751b92087fd0b06925ba6dd6314e06f089 # master
- name: Roave BC Check
uses: docker://nyholm/roave-bc-check-ga
uses: docker://nyholm/roave-bc-check-ga:latest@sha256:a9d3d932a4d3ba6a5a0563ef3788918a538198ee9c061a153f9b55caa8d3625f
21 changes: 17 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
name: Tests
on: [push, pull_request]

permissions:
contents: read

jobs:
build:
name: Build
Expand All @@ -11,14 +14,19 @@ jobs:
php: [ '7.1', '7.2', '7.3', '7.4', '8.0', '8.1']

steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit

- name: Set up PHP
uses: shivammathur/setup-php@v2
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2
with:
php-version: ${{ matrix.php }}
coverage: none

- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0

- name: Download dependencies
run: composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable
Expand All @@ -30,14 +38,19 @@ jobs:
name: Lowest deps
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit

- name: Set up PHP
uses: shivammathur/setup-php@v2
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2
with:
php-version: 7.3
coverage: none

- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0

- name: Download dependencies
run: composer update --no-interaction --prefer-dist --optimize-autoloader --prefer-stable --prefer-lowest
Expand Down
25 changes: 25 additions & 0 deletions .github/workflows/dependency-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Dependency Review Action
#
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
#
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: 'Dependency Review'
on: [pull_request]

permissions:
contents: read

jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit

- name: 'Checkout Repository'
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- name: 'Dependency Review'
uses: actions/dependency-review-action@0efb1d1d84fc9633afcdaad14c485cbbc90ef46c # v2.5.1
43 changes: 33 additions & 10 deletions .github/workflows/static.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
on: [pull_request]
name: Static analysis

permissions:
contents: read

jobs:
phpstan:
name: PHPStan
runs-on: ubuntu-20.04

steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit

- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0

- name: Setup PHP
uses: shivammathur/setup-php@v2
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2
with:
php-version: 8.0
coverage: none
tools: phpstan:0.12.92, cs2pr

- name: Download dependencies
uses: ramsey/composer-install@v1
uses: ramsey/composer-install@994bb194a4fefcf39449ccf0f7766a4318f1ac76 # v1

- name: PHPStan
run: phpstan analyze --no-progress --error-format=checkstyle | cs2pr
Expand All @@ -28,11 +36,16 @@ jobs:
runs-on: ubuntu-20.04

steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit

- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0

- name: Setup PHP
uses: shivammathur/setup-php@v2
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2
with:
php-version: 8.0
coverage: none
Expand All @@ -45,18 +58,23 @@ jobs:
name: Psalm
runs-on: ubuntu-20.04
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit

- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0

- name: Setup PHP
uses: shivammathur/setup-php@v2
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2
with:
php-version: 8.0
coverage: none
tools: vimeo/psalm:4.8.1

- name: Download dependencies
uses: ramsey/composer-install@v1
uses: ramsey/composer-install@994bb194a4fefcf39449ccf0f7766a4318f1ac76 # v1

- name: Psalm
run: psalm --no-progress --output-format=github
Expand All @@ -66,15 +84,20 @@ jobs:
runs-on: ubuntu-20.04

steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit

- name: Setup PHP
uses: shivammathur/setup-php@v2
uses: shivammathur/setup-php@44454db4f0199b8b9685a5d763dc37cbf79108e1 # v2
with:
php-version: 8.0
coverage: none
tools: composer-normalize

- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@ee0669bd1cc54295c223e0bb666b733df41de1c5 # v2.7.0

- name: Normalize
run: composer-normalize --dry-run
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,22 +232,22 @@ userinfo:

path:
"Normal" URL path according to RFC3986 section 3.3.
REGEX: (/? | (/[a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=:@]+)+)
REGEX: (/? | (/[a-zA-Z0-9-\._~%!\$&'\(\)\*\+,;=:@]+)+)

query:
"Normal" URL query according to RFC3986 section 3.4.
REGEX: [a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=:@]+
REGEX: [a-zA-Z0-9-\._~%!\$&'\(\)\*\+,;=:@]+

user:
This value can be URL encoded.
REGEX: [a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=]+
REGEX: [a-zA-Z0-9-\._~%!\$&'\(\)\*\+,;=]+

password:
This value can be URL encoded.
REGEX: [a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=]+
REGEX: [a-zA-Z0-9-\._~%!\$&'\(\)\*\+,;=]+

host:
REGEX: [a-zA-Z0-9-\._~%!\$&'\(\}\*\+,;=]+
REGEX: [a-zA-Z0-9-\._~%!\$&'\(\)\*\+,;=]+

post:
REGEX: [0-9]+
Expand Down
21 changes: 21 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Security Policy

## Supported Versions

Use this section to tell people about which versions of your project are
currently being supported with security updates.

| Version | Supported |
| ------- | ------------------ |
| 5.1.x | :white_check_mark: |
| 5.0.x | :x: |
| 4.0.x | :white_check_mark: |
| < 4.0 | :x: |

## Reporting a Vulnerability

Use this section to tell people how to report a vulnerability.

Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.
16 changes: 8 additions & 8 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
{
"name": "nyholm/dsn",
"type": "library",
"description": "Parse your DSN strings in a powerful and flexible way",
"license": "MIT",
"type": "library",
"keywords": [
"dsn",
"parser",
"dsn parser",
"database"
],
"homepage": "http://tnyholm.se",
"license": "MIT",
"authors": [
{
"name": "Tobias Nyholm",
"email": "tobias.nyholm@gmail.com"
}
],
"homepage": "http://tnyholm.se",
"require": {
"php": ">=7.1"
},
"require-dev": {
"symfony/phpunit-bridge": "^5.1"
},
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"Nyholm\\Dsn\\": "src/"
Expand All @@ -36,5 +31,10 @@
"psr-4": {
"Nyholm\\Dsn\\Test\\": "tests/"
}
},
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
}
}
29 changes: 23 additions & 6 deletions src/DsnParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class DsnParser
private const FUNCTION_REGEX = '#^([a-zA-Z0-9\+-]+):?\((.*)\)(?:\?(.*))?$#';
private const ARGUMENTS_REGEX = '#([^\s,]+\([^)]+\)(?:\?[^\s,]*)?|[^\s,]+)#';
private const UNRESERVED = 'a-zA-Z0-9-\._~';
private const SUB_DELIMS = '!\$&\'\(\}\*\+,;=';
private const SUB_DELIMS = '!\$&\'\(\)\*\+,;=';

/**
* Parse A DSN thay may contain functions. If no function is present in the
Expand Down Expand Up @@ -52,7 +52,10 @@ public static function parseFunc(string $dsn): DsnFunction
$arguments = $matches[1];
}

return new DsnFunction($functionName, array_map(\Closure::fromCallable([self::class, 'parseArguments']), $arguments), $parameters);
return new DsnFunction(
$functionName,
array_map(\Closure::fromCallable([self::class, 'parseArguments']), $arguments),
$parameters);
}

/**
Expand Down Expand Up @@ -113,7 +116,9 @@ private static function parseArguments(string $dsn)
private static function getDsn(string $dsn): Dsn
{
// Find the scheme if it exists and trim the double slash.
if (!preg_match('#^(?:(?<alt>['.self::UNRESERVED.self::SUB_DELIMS.'%]+:[0-9]+(?:[/?].*)?)|(?<scheme>[a-zA-Z0-9\+-\.]+):(?://)?(?<dsn>.*))$#', $dsn, $matches)) {
if (!preg_match(
'#^(?:(?<alt>['.self::UNRESERVED.self::SUB_DELIMS.'%]+:[0-9]+(?:[/?].*)?)|(?<scheme>[a-zA-Z0-9\+-\.]+):(?://)?(?<dsn>.*))$#',
$dsn, $matches)) {
throw new SyntaxException($dsn, 'A DSN must contain a scheme [a-zA-Z0-9\+-\.]+ and a colon.');
}
$scheme = null;
Expand All @@ -128,7 +133,9 @@ private static function getDsn(string $dsn): Dsn
}

// Parse user info
if (!preg_match('#^(?:(['.self::UNRESERVED.self::SUB_DELIMS.'%]+)?(?::(['.self::UNRESERVED.self::SUB_DELIMS.'%]*))?@)?([^\s@]+)$#', $dsn, $matches)) {
if (!preg_match(
'#^(?:(['.self::UNRESERVED.self::SUB_DELIMS.'%]+)?(?::(['.self::UNRESERVED.self::SUB_DELIMS.'%]*))?@)?([^\s@]+)$#',
$dsn, $matches)) {
throw new SyntaxException($dsn, 'The provided DSN is not valid. Maybe you need to url-encode the user/password?');
}

Expand All @@ -146,12 +153,22 @@ private static function getDsn(string $dsn): Dsn
if ('/' === $matches[3][0]) {
$parts = self::explodeUrl($matches[3], $dsn);

return new Path($scheme, $parts['path'], self::getQuery($parts), $authentication);
return new Path(
$scheme,
$parts['path'],
self::getQuery($parts),
$authentication);
}

$parts = self::explodeUrl('http://'.$matches[3], $dsn);

return new Url($scheme, $parts['host'], $parts['port'] ?? null, $parts['path'] ?? null, self::getQuery($parts), $authentication);
return new Url(
$scheme,
$parts['host'],
$parts['port'] ?? null,
$parts['path'] ?? null,
self::getQuery($parts),
$authentication);
}

/**
Expand Down
Loading