Skip to content

Normalize Windows temp dir in Given a directory step#330

Open
swissspidy wants to merge 2 commits intomainfrom
fix/real-realpath
Open

Normalize Windows temp dir in Given a directory step#330
swissspidy wants to merge 2 commits intomainfrom
fix/real-realpath

Conversation

@swissspidy
Copy link
Copy Markdown
Member

No description provided.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the directory validation logic in GivenStepDefinitions.php to better handle system temporary directories across different operating systems, including Mac OS X path prefixes and Windows case-insensitivity. The feedback suggests simplifying the repetitive path comparison logic by using a loop and a dynamic comparison function to improve readability and maintainability.

Comment on lines +67 to +70
$in_temp = 0 === ( $is_windows ? stripos( $dir, $temp_dir_original ) : strpos( $dir, $temp_dir_original ) )
|| 0 === ( $is_windows ? stripos( $dir, $temp_dir_real ) : strpos( $dir, $temp_dir_real ) )
|| 0 === ( $is_windows ? stripos( $dir, "/private{$temp_dir_original}" ) : strpos( $dir, "/private{$temp_dir_original}" ) )
|| 0 === ( $is_windows ? stripos( $dir, "/private{$temp_dir_real}" ) : strpos( $dir, "/private{$temp_dir_real}" ) );
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The logic for checking if the directory is within the temporary directory is quite repetitive and difficult to read. Since you are checking multiple candidates against the same directory using a conditional comparison function (stripos vs strpos), you can simplify this by using a loop. This improves maintainability and reduces the risk of errors when adding new candidates.

		$compare = $is_windows ? 'stripos' : 'strpos';
		$in_temp = false;
		foreach ( [ $temp_dir_original, $temp_dir_real ] as $temp_path ) {
			if ( 0 === $compare( $dir, $temp_path ) || 0 === $compare( $dir, "/private{$temp_path}" ) ) {
				$in_temp = true;
				break;
			}
		}

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 15, 2026

Codecov Report

❌ Patch coverage is 0% with 13 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Context/GivenStepDefinitions.php 0.00% 13 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the Behat Given an (empty|non-existent) <dir> directory step to handle Windows temp directory normalization more robustly by accounting for sys_get_temp_dir() vs realpath() differences and case-insensitive path comparisons.

Changes:

  • Track both the original temp dir and the realpath()’d temp dir and compare against both.
  • Use case-insensitive prefix checks on Windows to avoid temp-dir mismatches due to path casing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +67 to +70
$in_temp = 0 === ( $is_windows ? stripos( $dir, $temp_dir_original ) : strpos( $dir, $temp_dir_original ) )
|| 0 === ( $is_windows ? stripos( $dir, $temp_dir_real ) : strpos( $dir, $temp_dir_real ) )
|| 0 === ( $is_windows ? stripos( $dir, "/private{$temp_dir_original}" ) : strpos( $dir, "/private{$temp_dir_original}" ) )
|| 0 === ( $is_windows ? stripos( $dir, "/private{$temp_dir_real}" ) : strpos( $dir, "/private{$temp_dir_real}" ) );
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The temp-dir guard uses a raw prefix check (strpos/stripos === 0). This can be bypassed by paths that merely share the same prefix (e.g. temp dir /tmp vs directory /tmpfoo), which could allow deleting directories outside the temp tree. Consider enforcing a path-boundary check by normalizing/rtrimming both sides and comparing with an added trailing separator (or otherwise ensuring the next character is a separator/end-of-string) before calling remove_dir().

Copilot uses AI. Check for mistakes.
Comment thread src/Context/GivenStepDefinitions.php Outdated
Comment on lines +65 to +70
$is_windows = DIRECTORY_SEPARATOR === '\\';

$in_temp = 0 === ( $is_windows ? stripos( $dir, $temp_dir_original ) : strpos( $dir, $temp_dir_original ) )
|| 0 === ( $is_windows ? stripos( $dir, $temp_dir_real ) : strpos( $dir, $temp_dir_real ) )
|| 0 === ( $is_windows ? stripos( $dir, "/private{$temp_dir_original}" ) : strpos( $dir, "/private{$temp_dir_original}" ) )
|| 0 === ( $is_windows ? stripos( $dir, "/private{$temp_dir_real}" ) : strpos( $dir, "/private{$temp_dir_real}" ) );
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is Windows-specific (case-insensitive matching + sys_get_temp_dir vs realpath handling), but there’s no corresponding functional test ensuring Given an empty/non-existent <absolute-path> directory works on Windows when the temp path casing differs. Adding a @require-windows Behat scenario that builds an absolute temp path with different casing (e.g. via php -r + save STDOUT as {VAR}) would help prevent regressions.

Copilot uses AI. Check for mistakes.
Comment thread src/Context/GivenStepDefinitions.php Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@swissspidy swissspidy marked this pull request as ready for review April 17, 2026 08:07
@swissspidy swissspidy requested a review from a team as a code owner April 17, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants