Skip to content

Commit

Permalink
Validate variable name starts with a $
Browse files Browse the repository at this point in the history
  • Loading branch information
GromNaN committed Jan 27, 2025
1 parent 66977a6 commit 9b29819
Show file tree
Hide file tree
Showing 174 changed files with 1,762 additions and 693 deletions.
6 changes: 0 additions & 6 deletions generator/config/expressions.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
use MongoDB\Model\BSONArray;
use stdClass;

use function in_array;
use function ucfirst;

$bsonTypes = [
Expand Down Expand Up @@ -46,11 +45,6 @@
$expressions = [];
$resolvesToInterfaces = [];
foreach ($bsonTypes as $name => $acceptedTypes) {
// an expression can be a string with a $-prefixed field name
if (! in_array('string', $acceptedTypes)) {
$acceptedTypes[] = 'string';
}

$expressions[$name] = ['acceptedTypes' => $acceptedTypes];

$resolvesTo = 'resolvesTo' . ucfirst($name);
Expand Down
12 changes: 12 additions & 0 deletions generator/src/OperatorClassGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,18 @@ public function createClass(GeneratorDefinition $definition, OperatorDefinition
PHP);
}

if ($type->dollarPrefixedString) {
$namespace->addUseFunction('is_string');
$namespace->addUseFunction('str_starts_with');
$namespace->addUse(InvalidArgumentException::class);
$constructor->addBody(<<<PHP
if (is_string(\${$argument->propertyName}) && ! str_starts_with(\${$argument->propertyName}, '$')) {
throw new InvalidArgumentException('Argument \${$argument->propertyName} can be an expression, field paths and variable names must be prefixed by "$" or "$$".');
}
PHP);
}
}

// Set property from constructor argument
Expand Down
18 changes: 17 additions & 1 deletion generator/src/OperatorGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
use function ltrim;
use function sort;
use function sprintf;
use function str_starts_with;
use function ucfirst;
use function usort;

Expand Down Expand Up @@ -71,13 +72,19 @@ final protected function getType(string $type): ExpressionDefinition
* Expression types can contain class names, interface, native types or "list".
* PHPDoc types are more precise than native types, so we use them systematically even if redundant.
*
* @return object{native:string,doc:string,use:list<class-string>,list:bool,query:bool,javascript:bool}
* @return object{native:string,doc:string,use:list<class-string>,list:bool,query:bool,javascript:bool,dollarPrefixedString:bool}
*/
final protected function getAcceptedTypes(ArgumentDefinition $arg): stdClass
{
$nativeTypes = [];

$dollarPrefixedString = false;

foreach ($arg->type as $type) {
if (str_starts_with($type, 'resolvesTo')) {
$dollarPrefixedString = true;
}

$type = $this->getType($type);
$nativeTypes = array_merge($nativeTypes, $type->acceptedTypes);

Expand All @@ -91,6 +98,14 @@ final protected function getAcceptedTypes(ArgumentDefinition $arg): stdClass
$nativeTypes[] = Optional::class;
}

// If the argument accepts an expression, a $-prefixed string is accepted (field path or variable)
// Checked only if the argument does not already accept a string
if (in_array('string', $nativeTypes, true)) {
$dollarPrefixedString = false;
} elseif ($dollarPrefixedString) {
$nativeTypes[] = 'string';
}

$docTypes = $nativeTypes = array_unique($nativeTypes);
$use = [];

Expand Down Expand Up @@ -131,6 +146,7 @@ final protected function getAcceptedTypes(ArgumentDefinition $arg): stdClass
'list' => $listCheck,
'query' => $isQuery,
'javascript' => $isJavascript,
'dollarPrefixedString' => $dollarPrefixedString,
];
}

Expand Down
9 changes: 9 additions & 0 deletions src/Builder/Accumulator/AccumulatorAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/Builder/Accumulator/AvgAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/Builder/Accumulator/BottomNAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/Builder/Accumulator/CovariancePopAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions src/Builder/Accumulator/CovarianceSampAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/Builder/Accumulator/DerivativeAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 16 additions & 8 deletions src/Builder/Accumulator/ExpMovingAvgAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions src/Builder/Accumulator/FactoryTrait.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/Builder/Accumulator/FirstNAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions src/Builder/Accumulator/IntegralAccumulator.php

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 9b29819

Please sign in to comment.