From 63dc939081c3a892bda0be905c7c954324c63c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 27 May 2021 11:24:44 +0200 Subject: [PATCH] matrix-qrcode: Modify the QR code generation so mobile clients can decode --- matrix_qrcode/src/utils.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/matrix_qrcode/src/utils.rs b/matrix_qrcode/src/utils.rs index 6a30ff76..faff2f71 100644 --- a/matrix_qrcode/src/utils.rs +++ b/matrix_qrcode/src/utils.rs @@ -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 { 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")]