matrix-qrcode: Modify the QR code generation so mobile clients can decode

This commit is contained in:
Damir Jelić 2021-05-27 11:24:44 +02:00
parent 37c23f1761
commit 63dc939081

View file

@ -17,7 +17,7 @@ use std::convert::TryInto;
use base64::{decode_config, encode_config, STANDARD_NO_PAD};
#[cfg(feature = "decode_image")]
use image::{ImageBuffer, Luma};
use qrcode::QrCode;
use qrcode::{bits::Bits, EcLevel, QrCode, Version};
#[cfg(feature = "decode_image")]
use crate::error::DecodingError;
@ -73,7 +73,21 @@ pub(crate) fn to_qr_code(
shared_secret: &str,
) -> Result<QrCode, EncodingError> {
let data = to_bytes(mode, flow_id, first_key, second_key, shared_secret)?;
Ok(QrCode::new(data)?)
// Mobile clients seem to have trouble decoding the QR code that gets
// generated by `QrCode::new()` it seems to add a couple of data segments
// with different data modes/types. The parsers seem to assume a single
// data type and since we start with an ASCII `MATRIX` header the rest of
// the data gets treated as a string as well.
//
// We make sure that there isn't an ECI bit set and we just push the bytes,
// this seems to help since the decoder doesn't assume an encoding and
// treats everything as raw bytes.
let mut bits = Bits::new(Version::Normal(7));
bits.push_byte_data(&data)?;
bits.push_terminator(EcLevel::L)?;
Ok(QrCode::with_bits(bits, EcLevel::L)?)
}
#[cfg(feature = "decode_image")]