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

[BUG] QRCode::render() might return unexpected results when data segments were added before the call #246

Open
codemasher opened this issue Feb 26, 2024 · 0 comments

Comments

@codemasher
Copy link
Member

codemasher commented Feb 26, 2024

Describe the bug or unexpected behaviour

Version 5 introduced full support for mixed mode QR Codes by adding several segments via the methods QRCode::addByteSegment() [...] and then call QRCode::render() without the $data parameter.
However, it is possible to add several data segments and call the render method with data, which then adds another segment to the existing ones.

Steps to reproduce the behavior

  • invoke new QRCode instance
  • add one or more data segments
  • call QRCode::render() with the $data parameter set to a valid value
  • examine the rendered QR Code by scanning with a mobile device or using the built-in reader

Code sample (if applicable)

$qrcode = (new QRCode($options))
	->addNumericSegment('1312')
	->addAlphaNumSegment('ACAB')
;

$out = $qrcode->render('1312'); // rendered QR Code content: 1312ACAB1312

Expected behavior

The logical expectation is that the rendered QR Code would only contain the data given via the parameter or via the add*Segment() methods - this could be easily ensured by calling QRCode::clearSegments() after the $data check in line 79 in the code excerpt below.

/**
* Renders a QR Code for the given $data and QROptions, saves $file optionally
*/
public function render(string $data = null, string $file = null):mixed{
if($data !== null){
/** @var \chillerlan\QRCode\Data\QRDataModeInterface $dataInterface */
foreach(Mode::INTERFACES as $dataInterface){
if($dataInterface::validateString($data)){
$this->addSegment(new $dataInterface($data));
break;
}
}
}
return $this->renderMatrix($this->getQRMatrix(), $file);
}

However, I could see a legitimate reason for leaving the current behaivor as it is: adding an ECI designator before calling QRCode::render('<binary data>'), which is equivalent to calling QRCode::addEciSegment(<encoding>, '<binary data>') and then call the renderer without data.

$qrcode = (new QRCode($options))->addEciDesignator(ECICharset::WINDOWS_1251_CYRILLIC);

$out = $qrcode->render('<encoded binary data>'); // rendered QR Code content: <ECI header><encoded binary data>

I'm not exactly sure how to proceed with this (fix it or just document the behavior), so I'm leaving it here for a while to gather community opinions (maybe!?).

Environment:

  • Library version: v5.x
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

1 participant