Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix visibility of whitespace in config output #18527

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Girgias merged 2 commits into php:master from schneems:schneems/ini-high-vis
May 11, 2025

Conversation

Copy link
Contributor

@schneems schneems commented May 9, 2025
edited
Loading

When a config var has whitespace (especially trailing whitespace) it is hard to see. This commit wraps the values (if they exist) in a character so the difference is visually observable:

Before:

$ export PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d "
$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: /opt/homebrew/etc/php/8.4/conf.d 
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)

Note

The above output has trailing whitespace that is not visible, you can see it if you copy it into an editor.

After:

$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: "/opt/homebrew/etc/php/8.4/conf.d "
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)

Above the whitespace is now visible /opt/homebrew/etc/php/8.4/conf.d .

Close #18390

When a config var has whitespace (especially trailing whitespace) it is hard to see. This commit wraps the values (if they exist) in backticks so the difference is visually observable:
Before:
```
$ export PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d "
$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: /opt/homebrew/etc/php/8.4/conf.d 
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
```
> Note 
> The above output has trailing whitespace that is not visible, you can see it if you copy it into an editor:
After:
```
$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: `/usr/local/lib`
Loaded Configuration File: `/opt/homebrew/etc/php/8.4/conf.d `
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
```
Above the whitespace is visible `/opt/homebrew/etc/php/8.4/conf.d `.
Close php#18390 
Copy link
Member

@TimWolla TimWolla left a comment

Choose a reason for hiding this comment

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

Thank you for the PR. I think I would prefer double quotes as the indicator, as this would make the entire value copy and pasteable into a terminal without causing issues, i.e. I can just use the value and run vim "whatever I copied" to view a config file.

From a suggested comment php#18527 (review).
Before:
```
$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: `/usr/local/lib`
Loaded Configuration File: `/opt/homebrew/etc/php/8.4/conf.d `
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
```
After:
```
$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: "/opt/homebrew/etc/php/8.4/conf.d "
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
```
Copy link
Contributor Author

schneems commented May 9, 2025

@TimWolla seems good. I initially picked a backtick due to code literal format for markdown like this but I also agree that it's helpful to have a quote right there, especially for cases like "/dirs/like this that have spaces/in them" where copying and pasting the dir into a shell (a likely use case) would fail and the different segments might be treated as multiple arguments.

I'll generally defer character choice as a style decision for primary project maintainers/contributors. Updated with a new commit and description to match.

@TimWolla TimWolla requested a review from Girgias May 9, 2025 21:13
Copy link
Member

@Girgias Girgias left a comment

Choose a reason for hiding this comment

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

We usually use double quotes so this makes more sense than backticks.

Thank you!

@Girgias Girgias merged commit 331ac35 into php:master May 11, 2025
9 checks passed
Copy link
Member

I wonder if the string inside the quotes should've gotten escaped

Copy link
Member

Girgias commented May 11, 2025

I wonder if the string inside the quotes should've gotten escaped

Might be sensible, but isn't that a bit of a pre-existing issue?

Copy link
Member

I wonder if the string inside the quotes should've gotten escaped

Might be sensible, but isn't that a bit of a pre-existing issue?

I agree it's pre-existing. I realized it just now because we now explicitly add quotes around it 🙂 I can look for making a patch if this sounds good.

Girgias reacted with thumbs up emoji

Copy link
Member

Girgias commented May 11, 2025

I wonder if the string inside the quotes should've gotten escaped

Might be sensible, but isn't that a bit of a pre-existing issue?

I agree it's pre-existing. I realized it just now because we now explicitly add quotes around it 🙂 I can look for making a patch if this sounds good.

Yeah it makes sense to me to escape it :)

Copy link
Contributor Author

Thanks, all, for jumping on this quickly. Appreciate everything y'all do!

schneems added a commit to schneems/php-src that referenced this pull request May 14, 2025
In php#18527, I accidentally swapped the values. This is before my modification:
```
zend_printf("Configuration File (php.ini) Path: %s\n", PHP_CONFIG_FILE_PATH);
zend_printf("Loaded Configuration File: %s\n", php_ini_opened_path ? php_ini_opened_path : "(none)");
zend_printf("Scan for additional .ini files in: %s\n", php_ini_scanned_path ? php_ini_scanned_path : "(none)");
```
- "Loaded Configuration File" should be `php_ini_opened_path`
- "Scan for additional .ini files in" shoudl be `php_ini_scanned_path`
Copy link
Contributor

dzuelke commented May 14, 2025

This PR introduces a bug: php_ini_scanned_path and php_ini_opened_path are now swapped in the code.

It also doesn't add the same quotation marks to the output of php -i, so the behavior between that and php --ini is now inconsistent in this regard.

But most importantly, it causes a significant regression: there are a lot of projects out there that parse the output of php --ini, and suddenly having quotation marks will break them (a GitHub code search for "php --ini" grep or "php --ini" sed or "php --ini" awk gives slightly more insightful results than ORing the three in a single query, as the search then shows code first that has several different hits).

For example: https://github.com/shivammathur/setup-php/blob/cf4cade2721270509d5b1c766ab3549210a39a2a/src/scripts/unix.sh#L246

IMO this should be reverted, @nielsdos / @Girgias, until the BC impact has been thoroughly assessed.

TimWolla pushed a commit that referenced this pull request May 14, 2025
In #18527, I accidentally swapped the values. This is before my modification:
```
zend_printf("Configuration File (php.ini) Path: %s\n", PHP_CONFIG_FILE_PATH);
zend_printf("Loaded Configuration File: %s\n", php_ini_opened_path ? php_ini_opened_path : "(none)");
zend_printf("Scan for additional .ini files in: %s\n", php_ini_scanned_path ? php_ini_scanned_path : "(none)");
```
- "Loaded Configuration File" should be `php_ini_opened_path`
- "Scan for additional .ini files in" shoudl be `php_ini_scanned_path`
Copy link
Contributor Author

IMO this should be reverted, @nielsdos / @Girgias, until the BC impact has been thoroughly assessed.

Thankfully, this example works out of the box. It's a good thing @TimWolla advocated for quotes!

$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
$ cut -d '"' -f 2 < <(./sapi/cli/php --ini | grep '(php.ini)' | sed -e "s|.*: s*||")
/usr/local/lib

I agree with @dzuelke that perhaps the impact area is larger than previously realized. I think, at minimum, adding a NEWS entry and mentioning that it is changing is worth doing. I'm happy to send a PR, but feel like I'm accidentally racking up commits for my mistake already. @dzuelke did a good job of finding that other bug, I would like him to have the commit. Here's a (perhaps overly verbose) suggestion:

$ git diff
diff --git a/NEWS b/NEWS
index 706533b9c8..c63b8d32c3 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,10 @@ PHP NEWS
 . Drop support for -z CLI/CGI flag. (nielsdos)
 . Fixed GH-17956 - development server 404 page does not adapt to mobiles.
 (pascalchevrel)
+ . Change `php --ini` output to now wrap values in double quotes to better
+ show hidden whitespace. Scripts that rely on parsing this information
+ can use the `cut` to remove the quotes. For example https://github.com/shivammathur/setup-php/blob/cf4cade2721270509d5b1c766ab3549210a39a2a/src/scripts/unix.sh#L246
+ (schneems)
 - CURL:
 . Added CURLFOLLOW_ALL, CURLFOLLOW_OBEYCODE and CURLFOLLOW_FIRSTONLY

Moving forward, this suggests that perhaps a more stable, machine-readable CLI flag (or command) for such script authors would be good for stability. For example, something like php --ini=json that authors could then parse via jq (which is a pretty common system dependency at this point). This could be a compliment to the --ini=diff just added in 8.5 (thanks @TimWolla, yet again).

Copy link
Contributor

dzuelke commented May 15, 2025
edited
Loading

@schneems there is another option that I think solves both your original desire to highlight such a hard to spot error, and preserves backward compatibility: only quote the value if the TTY is a terminal.

That way, no regression is caused for any piping use case, but a human inspecting the output gets the quoting. This is similar to how many programs that output ANSI colors disable them once stdout is piped, so a perfectly common approach.

You can check for it like so (stdout is always FD number 1):

#ifdef PHP_WIN32
	/* Check if the Windows standard handle is redirected to file */
	stdout_is_tty = php_win32_console_fileno_is_console(1);
#elif HAVE_UNISTD_H
	/* Check if the file descriptor identifier is a terminal */
	stdout_is_tty = isatty(1);
#endif

And then use php_escape_shell_arg() on the string, it handles multibyte characters etc correctly and wraps everything in single quotes with correct escaping.

As I mentioned before, this quoting should maybe also be done for php -i (that code lives in ext/standard/info.c's php_print_info()) since a lot of people use that as well, and there might be a few other "locations of interest" in there - extension_dir, open_basedir, sys_temp_dir, upload_tmp_dir, user_dir come to mind.

schneems reacted with thumbs up emoji

schneems added a commit to schneems/php-src that referenced this pull request May 18, 2025
A comment in php#18527 mentioned that many scripts use `php—-ini` to bootstrap information about the system. Searching on GitHub confirms that many places will not work with quotes out of the box: https://github.com/search?q=content%3A%22php%20--ini%22&type=code.
Many seem to be variants on this pattern
```
$ echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
```
To preserve these existing scripts, we can detect when the output is a TTY to optionally quote them. This is the new behavior:
Output is a tty:
```
$ ./sapi/cli/php --ini 
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
```
Output is not a tty:
```
$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
```
schneems added a commit to schneems/php-src that referenced this pull request May 18, 2025
A comment in php#18527 mentioned that many scripts use `php—-ini` to bootstrap information about the system. Searching on GitHub confirms that many places will not work with quotes out of the box: https://github.com/search?q=content%3A%22php%20--ini%22&type=code.
Many seem to be variants on this pattern
```
$ echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
```
To preserve these existing scripts, we can detect when the output is a TTY to optionally quote them. This is the new behavior:
Output is a tty:
```
$ ./sapi/cli/php --ini 
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
```
Output is not a tty:
```
$ ./sapi/cli/php --ini
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: (none)
Scan for additional .ini files in: (none)
Additional .ini files parsed: (none)
```
schneems added a commit to schneems/php-src that referenced this pull request May 18, 2025
A comment in php#18527 mentioned that many scripts use `php—-ini` to bootstrap information about the system. Searching on GitHub confirms that many places will not work with quotes out of the box: https://github.com/search?q=content%3A%22php%20--ini%22&type=code.
Many seem to be variants on this pattern
```
$ echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
```
To preserve these existing scripts, we can detect when the output is a TTY to optionally quote them. This is the new behavior:
Output is a tty:
```
$ make -j$(nproc) &> /dev/null && env PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d " PHPRC="/opt/homebrew/etc/php/8.4" ./sapi/cli/php --ini
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: "/opt/homebrew/etc/php/8.4/php.ini"
Scan for additional .ini files in: "/opt/homebrew/etc/php/8.4/conf.d "
Additional .ini files parsed: (none)
```
Output is not a tty:
```
$ make -j$(nproc) &> /dev/null && env PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d " PHPRC="/opt/homebrew/etc/php/8.4" ./sapi/cli/php --ini | tee
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: /opt/homebrew/etc/php/8.4/php.ini
Scan for additional .ini files in: /opt/homebrew/etc/php/8.4/conf.d
Additional .ini files parsed: (none)
```
schneems added a commit to schneems/php-src that referenced this pull request May 18, 2025
A comment in php#18527 mentioned that many scripts use `php—-ini` to bootstrap information about the system. Searching on GitHub confirms that many places will not work with quotes out of the box: https://github.com/search?q=content%3A%22php%20--ini%22&type=code.
Many seem to be variants on this pattern
```
$ echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
```
To preserve these existing scripts, we can detect when the output is a TTY to optionally quote them. This is the new behavior:
Output is a tty:
```
$ make -j$(nproc) &> /dev/null && env PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d " PHPRC="/opt/homebrew/etc/php/8.4" ./sapi/cli/php --ini
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: "/opt/homebrew/etc/php/8.4/php.ini"
Scan for additional .ini files in: "/opt/homebrew/etc/php/8.4/conf.d "
Additional .ini files parsed: (none)
```
Output is not a tty:
```
$ make -j$(nproc) &> /dev/null && env PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d " PHPRC="/opt/homebrew/etc/php/8.4" ./sapi/cli/php --ini | tee
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: /opt/homebrew/etc/php/8.4/php.ini
Scan for additional .ini files in: /opt/homebrew/etc/php/8.4/conf.d
Additional .ini files parsed: (none)
```
schneems added a commit to schneems/php-src that referenced this pull request May 18, 2025
A comment in php#18527 mentioned that many scripts use `php—-ini` to bootstrap information about the system. Searching on GitHub confirms that many places will not work with quotes out of the box: https://github.com/search?q=content%3A%22php%20--ini%22&type=code.
Many seem to be variants on this pattern
```
$ echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
```
To preserve these existing scripts, we can detect when the output is a TTY to optionally quote them. This is the new behavior:
Output is a tty:
```
$ make -j$(nproc) &> /dev/null && env PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d " PHPRC="/opt/homebrew/etc/php/8.4" ./sapi/cli/php --ini
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: "/opt/homebrew/etc/php/8.4/php.ini"
Scan for additional .ini files in: "/opt/homebrew/etc/php/8.4/conf.d "
Additional .ini files parsed: (none)
```
Output is not a tty:
```
$ make -j$(nproc) &> /dev/null && env PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d " PHPRC="/opt/homebrew/etc/php/8.4" ./sapi/cli/php --ini | tee
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: /opt/homebrew/etc/php/8.4/php.ini
Scan for additional .ini files in: /opt/homebrew/etc/php/8.4/conf.d
Additional .ini files parsed: (none)
```
schneems added a commit to schneems/php-src that referenced this pull request May 18, 2025
A comment in php#18527 mentioned that many scripts use `php—-ini` to bootstrap information about the system. Searching on GitHub confirms that many places will not work with quotes out of the box: https://github.com/search?q=content%3A%22php%20--ini%22&type=code.
Many seem to be variants on this pattern
```
$ echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
```
To preserve these existing scripts, we can detect when the output is a TTY to optionally quote them. This is the new behavior:
Output is a tty:
```
$ make -j$(nproc) &> /dev/null && env PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d " PHPRC="/opt/homebrew/etc/php/8.4" ./sapi/cli/php --ini
Configuration File (php.ini) Path: "/usr/local/lib"
Loaded Configuration File: "/opt/homebrew/etc/php/8.4/php.ini"
Scan for additional .ini files in: "/opt/homebrew/etc/php/8.4/conf.d "
Additional .ini files parsed: (none)
```
Output is not a tty:
```
$ make -j$(nproc) &> /dev/null && env PHP_INI_SCAN_DIR="/opt/homebrew/etc/php/8.4/conf.d " PHPRC="/opt/homebrew/etc/php/8.4" ./sapi/cli/php --ini | tee
Configuration File (php.ini) Path: /usr/local/lib
Loaded Configuration File: /opt/homebrew/etc/php/8.4/php.ini
Scan for additional .ini files in: /opt/homebrew/etc/php/8.4/conf.d
Additional .ini files parsed: (none)
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@TimWolla TimWolla TimWolla approved these changes

@Girgias Girgias Girgias approved these changes

Assignees
No one assigned
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Debugging config problems with php --ini "hides" trailing whitespace

AltStyle によって変換されたページ (->オリジナル) /