Bacon / BaconQrCode

QR Code Generator for PHP
BSD 2-Clause "Simplified" License
1.83k stars 208 forks source link

Error QrCode generate - PHP8 (Index invalid or out of range) #92

Closed MarceloMelo1 closed 11 months ago

MarceloMelo1 commented 2 years ago

image

PhoenixBWS commented 2 years ago

This issue also prevents us from using endroid/qr-code in PHP8.1.x. Following error takes over:

Fatal error: Uncaught RuntimeException: Index invalid or out of range in /public_html/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php:106 Stack trace: #0 /public_html/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php(181): BaconQrCode\Encoder\MaskUtil::applyMaskPenaltyRule3() #1 /public_html/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php(228): BaconQrCode\Encoder\Encoder::calculateMaskPenalty() #2 /public_html/vendor/bacon/bacon-qr-code/src/Encoder/Encoder.php(119): BaconQrCode\Encoder\Encoder::chooseMaskPattern() #3 /public_html/vendor/endroid/qr-code/src/Bacon/MatrixFactory.php(18): BaconQrCode\Encoder\Encoder::encode() #4 /public_html/vendor/endroid/qr-code/src/Writer/PngWriter.php(29): Endroid\QrCode\Bacon\MatrixFactory->create() #5 /public_html/components/generator.php(27): Endroid\QrCode\Writer\PngWriter->write() #6 /public_html/index.php(27): include('...') #7 {main} thrown in /public_html/vendor/bacon/bacon-qr-code/src/Encoder/MaskUtil.php on line 106

endroid commented 2 years ago

Hi @DASPRiD by any chance do you have the time to look at this issue?

DASPRiD commented 2 years ago

Hi @DASPRiD by any chance do you have the time to look at this issue?

I just performed some cleanup and also migrated tests to Github actions, adding an integration test and adding PHP 8.0 and 8.1 to the test matrix. So far, all the tests are passing:

https://github.com/Bacon/BaconQrCode/actions/runs/1770110321

Could you supply a failing test case?

endroid commented 2 years ago

@DASPRiD Thank you. On my side all tests turn green too, however some users reported the same problem in a short time span. I also asked for their specific implementation in https://github.com/endroid/qr-code/issues/365 but their code also turns green in tests. In other words: no failing test case ;) Strangely enough some users have recently reported that the issue has disappeared on their side. Do you have any clue? I'm out of ideas.

acelaya commented 2 years ago

Is this matrix thing in any way related with the time it's generated? Maybe timezones or dates?

DASPRiD commented 2 years ago

@acelaya No, there's nothing time related in this library.

@endroid That is extremely weird. I have no idea what could have caused it for them, really. I read through your linked issue and to be honest, it doesn't really make sense.

Looking at the MaskUtil class, the only reason that error could ever happen would be if ByteMatrix would report a different width and height than the byte array it contains. But that doesn't make any sense, since the byte array is internally created based on the width and height parameters. It is even more confusing that this is only happening for some people, and only on PHP 8.0/8.1.

Since both your and my tests don't have any issues (I also tried to create a test case based on the issue on your repo), may I recommend the following to our users:

When you run into the issue, please edit the MaskUtil.php file in your vendor folder, and var_dump() the $array, $width and $height variables in the applyMaskPenaltyRule3 method, post the output on gist and link it here. That might give me some lead on the culprit.

gidbrn commented 2 years ago

@DASPRiD Thanks for the library!

The error occurs when enabling jit with parameters in php 8.0-8.1: opcache.jit_buffer_size=512M opcache.jit=tracing

The error does not occurs when enabling jit with parameters in php 8.0-8.1: opcache.jit_buffer_size=512M opcache.jit=function

It's PHP BUG!?

DASPRiD commented 2 years ago

@gidbrn Oh, really nice find!

I'd say yes, this is most likely a PHP bug, you might want to report it to them :)

endroid commented 2 years ago

@gidbrn good job, this issue was really difficult to trace.

hbernaciak commented 2 years ago

confirm that config like below cause same issue. [opcache] opcache.jit_buffer_size = 100M opcache.jit = 1255

@endroid @gidbrn have you already reported an issue with opcache? because opcache.jit=function is not the most optimal config for high performance, apart from that it works now as a workaround

endroid commented 2 years ago

@hbernaciak Good idea. I personally currently don't have the time to debug and report opcache issues, so go ahead if you like!

honzito commented 1 year ago

The bug is still there - even in PHP 8.2.6. The workaround, which worked for me is in src/Encoder/MaskUtil.php:

public static function applyMaskPenaltyRule3(ByteMatrix $matrix) : int {
    $penalty = 0;
    //$array = $matrix->getArray();
    $array = array_map(function ($value) { return (array)$value; }, (array)$matrix->getArray());  // SplFixedArray to array - there is probably bug in PHP 8.0 - 8.2+  - this is workaround
    ...

Just replace one line above...

kyosheek commented 1 year ago

Ran into same issue with jit = tracing today. Although everything was fine for like a month after installing and using package.

edit: forgot to mention @honzito's suggestion fixes the problem.

danog commented 11 months ago

A bugfix has been merged upstream in php-src, and will be available in PHP 8.3, 8.2.12 and 8.1.25.

DASPRiD commented 11 months ago

Perfect, gonna close the issue then, thanks for the information :)