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

Php config short array syntax #8029

Closed
wants to merge 14 commits into from

Conversation

JustAMurph
Copy link

Changed PhpConfig::dump() to use the Short Array Syntax. Tests are included and passing.

This for issue: #7804

It uses a new method in the PhpConfig.php file. It could be made to be more accessible by moving the method to "functions.php". However I'm not sure how beneficial that would be.

@dereuromark dereuromark added this to the 3.1.8 milestone Jan 14, 2016
* Similar to var_export() except it uses the Short Array Syntax;
*
* @param array $data Data to dump in Short Array Syntax
* @return string returns a parsable string representation of a short array syntax variable
Copy link
Member

Choose a reason for hiding this comment

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

@return string A parsable ...

public function shortArrayVarExport($data)
{
$varExport = var_export($data, true);
$pattern = ['/array \(/', '/\)/'];
Copy link
Member

Choose a reason for hiding this comment

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

Simply replacing all ")" with "]" looks risky. It could be part of a string for e.g.

@chinpei215
Copy link
Contributor

I agree with @ADmad. Sorry if I am wrong, but I think this change contains potential security risks. If it fails to replace some pair of parentheses, the generated php file would throw a parse error.

@dereuromark
Copy link
Member

I would use tokenizing, that will always work 100% and is safe.
See https://github.com/dereuromark/cakephp-upgrade/blob/master/Console/Command/ArraysShell.php#L70 for example.

@JustAMurph
Copy link
Author

If it's only matching based on the return of var_export(), when would it not be safe to use? Since var_export is supposed to always return a valid PHP code string. That would mean the data for preg_replace is always correct?

@chinpei215
Copy link
Contributor

What happens if the variable contains an object?
Anyway, shortArrayVarExport() couldn't be more secure than var_export(). That is a risk factor. We have to write a perfect array parser. Otherwise, we will see a new security release in future.

{
$varExport = var_export($data, true);
$pattern = [
'/array \(/', // Matches opening "array("
Copy link
Member

Choose a reason for hiding this comment

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

Won't this also match string values like 'I am a silly array ( value'?

@markstory
Copy link
Member

I share @chinpei215's concerns. This code could run into issues with exported objects, and formatting issues from with PHP. Another approach would be to partially re-implement var_export similar to how Debugger::exportVar() does. You could continue using var_export() for the values, and only use custom code for dumping the array structure/indentation.

@JustAMurph
Copy link
Author

I've taken advice, and removed the search and replace. It now builds the array structure / indentation itself. Values/Objects are still passed to var_export. Hopefully this should be a better implementation.


$filename = $this->_getFilePath($key);
return file_put_contents($filename, $contents) > 0;
}

/**
*
Copy link
Member

Choose a reason for hiding this comment

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

A newline too much by the way.

@chinpei215
Copy link
Contributor

@JustAMurph I respect your efforts. So It’s hard for me to say this but I don't think this is a good approach.
If the variable contains a reference of an array, this method would never return.
var_export() also doesn't work in such a case but it can return something.

I think @dereuromark's idea might be not bad. But I don't think that is safe because people often make a mistake. That would work if we could make a perfect code.

It's very hard for me to explain abstract something by my English, but..
Roughly, there are two kinds of codes in an application - a secure code (e.g. calling a single function) and a dangerous code (e.g. calling functions recursively).
There are also two kinds of zones in an application - a secure zone (e.g. logging) and a dangerous zone (e.g. dumping php file).
A dangerous code written in a secure zone might be secure. But a dangerous code written in a dangerous zone is really dangerous. So we should avoid it as much as possible.

What about sending a request for this feature to PHP core team? I don't think this is an issue of CakePHP.

@dereuromark
Copy link
Member

@chinpei215 I had similar thoughts. Sometimes I wonder what the core PHP people think... Why didn't they provide a var_export($expression, $return, EXPORT_SHORT_ARRAY) option similar to json_encode() options once they changed the arrays in PHP5.4? This is clearly something they forgot already back in PHP5.4.0.

@chinpei215
Copy link
Contributor

@dereuromark
Copy link
Member

The justification for short array syntax - that it is short - doesn't matter for generated code.

What matters is that the output is predictable across PHP versions, for that reason it doesn't make sense to change the format of the output in order to comply with a PSR that doesn't apply to internals, and was never meant too.

Definitely, not a bug ...

Someone really didn't think things through :) The output is not PSR related, its PHP syntax related, thus is is a missing core PHP functionality. Well, Well... Oh and I like the output is predictable contradiction in the same sentence. Consistency is part of predictability IMO.

@chinpei215
Copy link
Contributor

@dereuromark I am not sure, but request for adding option EXPORT_SHORT_ARRAY might be acceptable.

$key = (is_int($key)) ? (int)$key : "'$key'";

if (is_array($value)) {
$value = PHP_EOL . $this->shortArrayVarExport($value, $indent + 1);
Copy link
Member

Choose a reason for hiding this comment

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

We could run out of stackframes if someone tries to dump a monster array.

@dereuromark
Copy link
Member

I think @dereuromark's idea might be not bad. But I don't think that is safe because people often make a mistake. That would work if we could make a perfect code.

We don't want to change the output semantics, we dont want to make it safer than the original output either. We just dont want to introduce new issues.
So tokenizing, replacing, done. That is as simple as it gets and does not need stackframes :)

@markstory markstory modified the milestones: 3.1.8, 3.1.9 Jan 24, 2016
@markstory
Copy link
Member

I'm going to close this pull request. I'm not sure having PSR2 compatible generated coded is worth the complexity and risk we expose ourselves to.

@markstory markstory closed this Jan 25, 2016
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.

None yet

5 participants