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

Crash when '9223372036854775807' literal is used as an array key #9498

Closed
MoonE opened this issue Mar 12, 2023 · 3 comments · Fixed by #9499
Closed

Crash when '9223372036854775807' literal is used as an array key #9498

MoonE opened this issue Mar 12, 2023 · 3 comments · Fixed by #9499

Comments

@MoonE
Copy link
Contributor

MoonE commented Mar 12, 2023

https://psalm.dev/r/cbd73b78e5

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/cbd73b78e5
<?php
['9223372036854775807' => ''];
Psalm encountered an internal error:

/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php: Cannot assign float to property Psalm\Internal\Analyzer\Statements\Expression\ArrayCreationInfo::$int_offset of type int

@MoonE
Copy link
Contributor Author

MoonE commented Mar 12, 2023

PHP Fatal error: Uncaught Error: Cannot add element to the array as the next element is already occupied

Thrown from php when executing this code:

<?php
$x = [PHP_INT_MAX => ''];
$x[] = '';

When int_offset would store the current offset (initialized with -1) instead of the next offset it would be possible to check if the array is already full and add a message.

diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php
index 0c0e30fcc..b2a64ef6d 100644
--- a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php
+++ b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php
@@ -333,11 +333,11 @@ class ArrayAnalyzer
                 } elseif ($key_type->isSingleIntLiteral()) {
                     $item_key_value = $key_type->getSingleIntLiteral()->value;
 
-                    if ($item_key_value >= $array_creation_info->int_offset) {
+                    if ($item_key_value > $array_creation_info->int_offset) {
                         if ($item_key_value === $array_creation_info->int_offset) {
                             $item_is_list_item = true;
                         }
-                        $array_creation_info->int_offset = $item_key_value + 1;
+                        $array_creation_info->int_offset = $item_key_value;
                     }
                 }
             } else {
@@ -345,7 +345,11 @@ class ArrayAnalyzer
             }
         } else {
             $item_is_list_item = true;
-            $item_key_value = $array_creation_info->int_offset++;
+            if ($array_creation_info->int_offset < PHP_INT_MAX) {
+                $item_key_value = ++$array_creation_info->int_offset;
+            } else {
+                // FIXME: Cannot insert array element, php does not allow it.
+            }
             $key_atomic_type = new TLiteralInt($item_key_value);
             $array_creation_info->item_key_atomic_types[] = $key_atomic_type;
             $key_type = new Union([$key_atomic_type]);

Code is duplicated in SimpleTypeInferer and ArrayAnalyzer and should be fixed there, too.

@weirdan
Copy link
Collaborator

weirdan commented Mar 12, 2023

Code is duplicated in SimpleTypeInferer and ArrayAnalyzer and should be fixed there, too.

Good point.

PHP Fatal error: Uncaught Error: Cannot add element to the array as the next element is already occupied

I think we better fix it separately from the original problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants