From 2e0e81fb8e594f8375f2174c4bd8ca5fecb2dc53 Mon Sep 17 00:00:00 2001 From: naingaunglwin-dev Date: Thu, 18 Sep 2025 12:53:32 +0630 Subject: [PATCH 1/4] implement github action --- .github/workflows/tests.yml | 41 +++++++++++++++++++++++++++++++++++++ composer.json | 3 +++ 2 files changed, 44 insertions(+) create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..7fb0d41 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,41 @@ +name: Tests + +on: + push: + branches: [ "master" ] + pull_request: + branches: [ "master" ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 8.2 + + - name: Validate composer.json and composer.lock + run: composer validate --strict + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress --no-suggest + + - name: Run test suite + run: composer test diff --git a/composer.json b/composer.json index d7081fb..f986f9e 100644 --- a/composer.json +++ b/composer.json @@ -22,5 +22,8 @@ }, "require-dev": { "phpunit/phpunit": "^11.5" + }, + "scripts": { + "test": "vendor/bin/phpunit tests" } } From 77d4e463520d4e9605038eb9583ce0790de89ce6 Mon Sep 17 00:00:00 2001 From: naingaunglwin-dev Date: Thu, 18 Sep 2025 13:07:46 +0630 Subject: [PATCH 2/4] remove version from composer.json --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index f986f9e..a67bfe6 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,6 @@ "name": "naingaunglwin-dev/dotenv", "description": "Simple and lightweight php dotenv library", "minimum-stability": "dev", - "version": "2.0.0", "prefer-stable": true, "license": "MIT", "authors": [ From 8f54a1d8d027a89643bd88f44f38733b7e05f790 Mon Sep 17 00:00:00 2001 From: naingaunglwin-dev Date: Thu, 18 Sep 2025 15:02:38 +0630 Subject: [PATCH 3/4] add absolute check condition to PathResolver::normalize --- src/PathResolver.php | 4 ++++ tests/EnvTest.php | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/src/PathResolver.php b/src/PathResolver.php index b359b53..90f2af8 100644 --- a/src/PathResolver.php +++ b/src/PathResolver.php @@ -107,6 +107,10 @@ public static function isAbsolute(string $path): bool */ public static function normalize(string $path): string { + if (self::isAbsolute($path)) { + return str_replace(['/', '\\'], self::DS, $path); + } + return trim(str_replace(['/', '\\'], self::DS, $path), self::DS); } } diff --git a/tests/EnvTest.php b/tests/EnvTest.php index fc30c7e..f63772d 100644 --- a/tests/EnvTest.php +++ b/tests/EnvTest.php @@ -146,6 +146,15 @@ public function testThrowExceptionIfEnvFileNotFound() $env->load(); } + public function testEnvFileLoadWithCustomPath() + { + $file = $this->createEnvFile('.env', "FOO=bar\n"); + + $env = Env::create(loader: new DotenvLoader('.env', resolver: new PathResolver($this->dir))); + + $this->assertSame('bar', $env->get('FOO')); + } + public function testThrowExceptionEnvLoadWithGuessLoaderForUnregisteredFileType() { $file = $this->createEnvFile('env.txt', "APP_TEST=true"); From 8a9dcf06185a73f5109b3b8f03ba5fcd6938bf8a Mon Sep 17 00:00:00 2001 From: naingaunglwin-dev Date: Thu, 18 Sep 2025 16:48:17 +0630 Subject: [PATCH 4/4] check file is readable or not in file BaseLoader::resolveFiles --- src/Loader/BaseLoader.php | 11 ++++++++++- src/Loader/DotenvLoader.php | 2 +- src/Loader/JsonLoader.php | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Loader/BaseLoader.php b/src/Loader/BaseLoader.php index de27465..1ae6ba9 100644 --- a/src/Loader/BaseLoader.php +++ b/src/Loader/BaseLoader.php @@ -2,6 +2,7 @@ namespace NAL\Dotenv\Loader; +use NAL\Dotenv\Exceptions\UnableToOpenFileException; use NAL\Dotenv\Parser\ParserInterface; use NAL\Dotenv\PathResolver; @@ -54,7 +55,15 @@ protected function getDefaultFile(): string */ protected function resolveFiles(): array { - return array_map(fn ($file) => $this->resolver->resolve($file), $this->files); + return array_map(function ($file) { + $file = $this->resolver->resolve($file); + + if (!is_file($file) || !is_readable($file)) { + throw new UnableToOpenFileException($file); + } + + return $file; + }, $this->files); } /** diff --git a/src/Loader/DotenvLoader.php b/src/Loader/DotenvLoader.php index dd84624..3dd6c79 100644 --- a/src/Loader/DotenvLoader.php +++ b/src/Loader/DotenvLoader.php @@ -43,7 +43,7 @@ public function load(): array $handle = @fopen($file, 'r'); if ($handle === false) { - throw new UnableToOpenFileException($file); + throw new UnableToOpenFileException($file); // @codeCoverageIgnore } $contents = fread($handle, filesize($file)); diff --git a/src/Loader/JsonLoader.php b/src/Loader/JsonLoader.php index a8c6f96..b2e84af 100644 --- a/src/Loader/JsonLoader.php +++ b/src/Loader/JsonLoader.php @@ -46,7 +46,7 @@ public function load(): array $handle = @fopen($file, 'r'); if ($handle === false) { - throw new UnableToOpenFileException($file); + throw new UnableToOpenFileException($file); // @codeCoverageIgnore } $content = fread($handle, filesize($file));