Skip to content
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

[Console] ArgvInput - Short command input using incorrect environment name #26136

Closed
codereviewvideos opened this issue Feb 10, 2018 · 16 comments

Comments

@codereviewvideos
Copy link

Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version 3.4.5-DEV

There appears to be a bug here, but I haven't been able to figure out a solution.

The phpunit tests pass.

If I run bin/console cac:cl -e=dev I'm seeing:

PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.dev/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 291
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.dev/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.dev/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.dev/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:291

The bigger issue is:

In FileLocator.php line 44:

  The file "/var/www/api.codereviewvideos.dev/app/config/config_=dev.yml" does not exist.

The =dev bit being the problem.

I tracked this down to the change below in getParameterOption.

return substr($token, strlen($leading));

Looking at the old code:

return substr($token, $pos + 1);

If I change to:

return substr($token, strlen($leading) + 1);

Then the command completes - but the strpos warnings remain.

I added the following just before the new return on line 321:

\Doctrine\Common\Util\Debug::dump([
    'value' => $value,
    'token' => $token,
    '0 === strpos($value, "--")' => 0 === strpos($value, '--'),
    'leading' => $leading,
    'strlen($leading)' => strlen($leading),
    'substr($token, strlen($leading))' => substr($token, strlen($leading) + 1),
]);

If I e.g. run the cache:clear command again I see:

array (size=6)
  'value' => string '-e' (length=2)
  'token' => string '-e=dev' (length=6)
  '0 === strpos($value, "--")' => boolean false
  'leading' => string '-e' (length=2)
  'strlen($leading)' => int 2
  'substr($token, strlen($leading))' => string 'dev' (length=3)

Looks good.

Now if I run the tests I see 8 failures (provideGetParameterOptionValues) e.g:

8) Symfony\Component\Console\Tests\Input\ArgvInputTest::testGetParameterOptionEqualSign with data set #13 (array('app/console', 'foo:bar', '--', '--env=dev'), '--env', false, 'dev')
->getParameterOption() returns the expected value
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'dev'
+'ev'

One extra thing, this only affects the short options (-e=dev), using the longer form (--env=dev) does not trigger this issue. However, the strpos(): Empty needle issue occurs for both long and short form.

Sorry I haven't been able to figure this out, but I hope this helps in some way in tracking down the root cause. Thank you for your time.

@chalasr
Copy link
Member

chalasr commented Feb 10, 2018

ping @greg-1-anderson this seems to be related to the changes made in #25893, could you please have a look?

@greg-1-anderson
Copy link
Contributor

When using short options, -e=dev is incorrect. -edev is the correct form to use with short options that have values.

Explanation is in the summary of #25825; see also #25825 (comment).

@greg-1-anderson
Copy link
Contributor

Is the "empty needle" error happening on current (dev) Symfony code? That shouldn't happen with input of -e=dev; you should just get a value of =dev in that instance. I'll try to reproduce in a bit when I have some time.

@codereviewvideos
Copy link
Author

Hi @greg-1-anderson

Regarding the short options - I did not know that e.g. -e=dev was incorrect. Thank you for making me aware of this.

Having checked, there is no issue when correctly using the short option syntax.

This said, in my opinion it would be confusing to suddenly stop "supporting" the incorrect short hand syntax in a patch release.

On the empty needle issue, I put a print_r($values); on ArgvInput:279

(3.4.4)

php bin/console cac:cl -e acceptance
Array
(
    [0] => --no-debug
    [1] => 
)
Array
(
    [0] => --ansi
)
Array
(
    [0] => --no-ansi
)
Array
(
    [0] => --no-interaction
    [1] => -n
)
Array
(
    [0] => --quiet
    [1] => -q
)
Array
(
    [0] => -vvv
)
Array
(
    [0] => --verbose=3
)
Array
(
    [0] => -vv
)
Array
(
    [0] => --verbose=2
)
Array
(
    [0] => -v
)
Array
(
    [0] => --verbose=1
)
Array
(
    [0] => --verbose
)
Array
(
    [0] => --version
    [1] => -V
)
Array
(
    [0] => --help
    [1] => -h
)

 // Clearing the cache for the acceptance environment with debug true  

[OK] Cache for the "acceptance" environment (debug=true) was successfully cleared.

(3.4.x-dev 01ccae8)

bin/console cac:cl -e acceptance
Array
(
    [0] => --no-debug
    [1] => 
)
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 290
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:290
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 290
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:290
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 290
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:290
Array
(
    [0] => --ansi
)
Array
(
    [0] => --no-ansi
)
Array
(
    [0] => --no-interaction
    [1] => -n
)
Array
(
    [0] => --quiet
    [1] => -q
)
Array
(
    [0] => -vvv
)
Array
(
    [0] => --verbose=3
)
Array
(
    [0] => -vv
)
Array
(
    [0] => --verbose=2
)
Array
(
    [0] => -v
)
Array
(
    [0] => --verbose=1
)
Array
(
    [0] => --verbose
)
Array
(
    [0] => --version
    [1] => -V
)
Array
(
    [0] => --help
    [1] => -h
)

 // Clearing the cache for the acceptance environment with debug true 

[OK] Cache for the "acceptance" environment (debug=true) was successfully cleared.

To answer your questions specifically:

Is the "empty needle" error happening on current (dev) Symfony code?

yes (I'm using commit hash 01ccae8)

That shouldn't happen with input of -e=dev; you should just get a value of =dev in that instance.

This is what I see:

bin/console cac:cl -e=acceptance
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 289
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:289
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 289
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:289

In FileLocator.php line 44:
                                                                                                         
  The file "/var/www/api.codereviewvideos.acceptance/app/config/config_=acceptance.yml" does not exist.



---

bin/console cac:cl -e=dev       
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 289
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:289
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 289
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:289

In FileLocator.php line 44:
                                                                                                  
  The file "/var/www/api.codereviewvideos.acceptance/app/config/config_=dev.yml" does not exist.

Again, sorry I haven't been able to find a reason as to why this is happening.

Thanks for your time and help,

Chris

@greg-1-anderson
Copy link
Contributor

This said, in my opinion it would be confusing to suddenly stop "supporting" the incorrect short hand syntax in a patch release.

The "support" for -e=dev was inconsistent. getParameterOption() expected the =, but getOption() did not allow it. My opinion is that it is better to eliminate this inconsistency as soon as possible, but I'm not a maintainer here.

PHP Warning: strpos(): Empty needle in

This should definitely be fixed.

@greg-1-anderson
Copy link
Contributor

@codereviewvideos I think that the root bug is here:

https://github.com/codereviewvideos/lets-explore-symfony-4/blob/9cd23e3387a563c03504a8fe8addcd71e10b5b68/bin/console#L27

$debug = ($_SERVER['APP_DEBUG'] ?? ('prod' !== $env)) && !$input->hasParameterOption(['--no-debug', '']);

Is there any reason that you need to pass an empty string as the last element to the parameter to hasParameterOption()? You should not get the warning above if you remove this entry, and test only for --no-debug.

That said, I think it would be reasonable to fix up Symfony so that it does not emit a warning when an empty string is passed to the hasParameterOption() argument array, as it did not warn in this way in previous releases.

greg-1-anderson added a commit to greg-1-anderson/symfony that referenced this issue Feb 12, 2018
… getParameterOption is passed invalid parameters.
@greg-1-anderson
Copy link
Contributor

@codereviewvideos See #26156

@Simperfit
Copy link
Contributor

I think we need to reword this one for a minor (by deprecating things we don't want to support) and a major release to avoid all this bugs and to be able to support all the syntax we need to support. WDYT @greg-1-anderson @chalasr ?

@chalasr
Copy link
Member

chalasr commented Feb 13, 2018

@Simperfit We need to fix that bug where it has been introduced (2.7), new deprecations cannot be added there. If you think something is buggy and should go away in the next major, please consider opening a dedicated discussion.

stof added a commit to symfony/symfony-standard that referenced this issue Feb 15, 2018
This PR was merged into the 3.4 branch.

Discussion
----------

Improve the console script

- look for the `--env` and `--no-debug` only before a `--` separator, to respect the support for `--`
- avoid passing an empty string as parameter option name (which would never match anyway, but causes php warning is some Symfony versions instead of being ignored silently, because of symfony/symfony#26136).

Same change than symfony/recipes#367

Commits
-------

126ce57 Improve the console script
@fabpot fabpot closed this as completed Feb 16, 2018
fabpot added a commit that referenced this issue Feb 16, 2018
…() (greg-1-anderson)

This PR was squashed before being merged into the 2.7 branch (closes #26156).

Discussion
----------

Fixes #26136: Avoid emitting warning in hasParameterOption()

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #26136
| License       | MIT
| Doc PR        | n/a

When hasParameterOption / getParameterOption is passed invalid parameters, a warning may be emitted. While the root cause of the warning is an invalid parameter supplied by the caller, earlier versions of Symfony accepted these parameters, which were effectively ignored.

In the context of these methods, what I mean by "invalid parameter" is an empty string, which is the correct datatype, but is not ever a useful thing to provide to these methods. Since empty strings here did not cause a problem in previous versions, and since Symfony is used by all sorts of projects for all sorts of purposes, it seems best to continue to be flexible about the parameters accepted by Symfony APIs.

Commits
-------

b32fdf1 Fixes #26136: Avoid emitting warning in hasParameterOption()
@Simperfit
Copy link
Contributor

@codereviewvideos does it fix the bug for you ?

@codereviewvideos
Copy link
Author

Not to the best of my knowledge, apologies not looked into this at all today. Here's my output from a quick test:

composer update --prefer-dist
    
Package operations: 0 installs, 2 updates, 0 removals
  - Updating symfony/symfony (v3.4.4 => 3.4.x-dev 7bcccef):  Checking out 7bcccefb60


bin/console cac:cl -e dev
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 289
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:289
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 289
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:289
PHP Warning:  strpos(): Empty needle in /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php on line 289
PHP Stack trace:
PHP   1. {main}() /var/www/api.codereviewvideos.acceptance/bin/console:0
PHP   2. Symfony\Component\Console\Input\ArgvInput->hasParameterOption() /var/www/api.codereviewvideos.acceptance/bin/console:21
PHP   3. strpos() /var/www/api.codereviewvideos.acceptance/vendor/symfony/symfony/src/Symfony/Component/Console/Input/ArgvInput.php:289

 // Clearing the cache for the dev environment with debug true                                                          

                                                                                                                        
 [OK] Cache for the "dev" environment (debug=true) was successfully cleared.                                            
                                                                                                                       

Do you see the same?

@greg-1-anderson
Copy link
Contributor

Try 9d3d237 on the 2.7 branch; I'm not sure this commit has made it to 3.4 or other branches.

@codereviewvideos
Copy link
Author

Ok - really sorry, as I say, not looked into this at all as of yet. I have a real life issue that's taking precedence currently. I have some 2.x projects around which I will try this on and update. Sorry again for the delay.

Chris

nicolas-grekas added a commit that referenced this issue Feb 19, 2018
* 2.7:
  Clean calls to http_build_query()
  [HttpFoundation] Fix missing "throw" in JsonResponse
  Improve the documentation of
  Suppress warning from sapi_windows_vt100_support on stream other than STDIO
  removed extra-verbose comments
  Fixes #26136: Avoid emitting warning in hasParameterOption()
  Added a README entry to the PR template
  [HttpFoundation] Add x-zip-compressed to MimeTypeExtensionGuesser.
  [DI] Add null check for removeChild
nicolas-grekas added a commit that referenced this issue Feb 22, 2018
* 2.8:
  Another PR template tweak
  [PropertyInfo] ReflectionExtractor: give a chance to other extractors if no properties
  Clean calls to http_build_query()
  [WebProfilerBundle] limit ajax request to 100 and remove the last one
  [HttpFoundation] Fix missing "throw" in JsonResponse
  Improve the documentation of
  Suppress warning from sapi_windows_vt100_support on stream other than STDIO
  removed extra-verbose comments
  Fixes #26136: Avoid emitting warning in hasParameterOption()
  Added a README entry to the PR template
  [HttpFoundation] Add x-zip-compressed to MimeTypeExtensionGuesser.
  [DI] Add null check for removeChild
nicolas-grekas added a commit that referenced this issue Feb 22, 2018
* 3.4:
  [Translation] Process multiple segments within a single unit.
  Document the container.autowiring.strict_mode option
  fix custom radios/inputs for checkbox/radio type
  Another PR template tweak
  [FrameworkBundle] Add missing XML config for circular_reference_handler. Add tests.
  fix CS
  [PropertyInfo] ReflectionExtractor: give a chance to other extractors if no properties
  Clean calls to http_build_query()
  [WebProfilerBundle] limit ajax request to 100 and remove the last one
  Add support for URL-like DSNs for the PdoSessionHandler
  [HttpFoundation] Fix missing "throw" in JsonResponse
  Improve the documentation of
  Suppress warning from sapi_windows_vt100_support on stream other than STDIO
  removed extra-verbose comments
  Fixes #26136: Avoid emitting warning in hasParameterOption()
  Added a README entry to the PR template
  [HttpFoundation] Add x-zip-compressed to MimeTypeExtensionGuesser.
  [DI] Add null check for removeChild
nicolas-grekas added a commit that referenced this issue Feb 22, 2018
* 4.0:
  [Translation] Process multiple segments within a single unit.
  Document the container.autowiring.strict_mode option
  fix custom radios/inputs for checkbox/radio type
  Another PR template tweak
  [FrameworkBundle] Add missing XML config for circular_reference_handler. Add tests.
  fix CS
  [PropertyInfo] ReflectionExtractor: give a chance to other extractors if no properties
  Clean calls to http_build_query()
  [WebProfilerBundle] limit ajax request to 100 and remove the last one
  Add support for URL-like DSNs for the PdoSessionHandler
  removed version in @Final @internal for version < 4.0
  [HttpFoundation] Fix missing "throw" in JsonResponse
  Improve the documentation of
  Suppress warning from sapi_windows_vt100_support on stream other than STDIO
  removed extra-verbose comments
  Fixes #26136: Avoid emitting warning in hasParameterOption()
  Added a README entry to the PR template
  [HttpFoundation] Add x-zip-compressed to MimeTypeExtensionGuesser.
  [DI] Add null check for removeChild
This was referenced Feb 28, 2018
This was referenced Mar 1, 2018
@benbor
Copy link

benbor commented Mar 3, 2018

Hi guys. @greg-1-anderson I agree with your

The "support" for -e=dev was inconsistent.

but, this case had worked before this fix was merged. At now all commands witch called with -e=prod are broken (fyi: with very unusual error Parse error: syntax error, unexpected '=', expecting ',' or ')' in /symfony/var/cache/=prod/src=prodDebugProjectContainer.php:5), so it hard to understand what happens.
Console Input documentation doesn't have any notes about that.
Also release changelog doesn't have any information about BC break.

I propose the following:

cc @nicolas-grekas

@greg-1-anderson
Copy link
Contributor

Good suggestions, @benbor. See symfony/symfony-docs#9387 and #26378.

The changelog has already gone out; perhaps someone can still update that retroactively, though.

@AlexanderMatveev
Copy link

+1

sandergo90 pushed a commit to sandergo90/symfony that referenced this issue Jul 4, 2019
* 4.0:
  [Translation] Process multiple segments within a single unit.
  Document the container.autowiring.strict_mode option
  fix custom radios/inputs for checkbox/radio type
  Another PR template tweak
  [FrameworkBundle] Add missing XML config for circular_reference_handler. Add tests.
  fix CS
  [PropertyInfo] ReflectionExtractor: give a chance to other extractors if no properties
  Clean calls to http_build_query()
  [WebProfilerBundle] limit ajax request to 100 and remove the last one
  Add support for URL-like DSNs for the PdoSessionHandler
  removed version in @Final @internal for version < 4.0
  [HttpFoundation] Fix missing "throw" in JsonResponse
  Improve the documentation of
  Suppress warning from sapi_windows_vt100_support on stream other than STDIO
  removed extra-verbose comments
  Fixes symfony#26136: Avoid emitting warning in hasParameterOption()
  Added a README entry to the PR template
  [HttpFoundation] Add x-zip-compressed to MimeTypeExtensionGuesser.
  [DI] Add null check for removeChild
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants