Skip to content

Commit

Permalink
Add small fix and testing of base64url QR option.
Browse files Browse the repository at this point in the history
Fixed unit test not compiling since QR code encoding options changed.
Fixed couple small issues decoding email qr codes.
Added some basic tests for base64url encoding/decoding, as emails.
  • Loading branch information
wcjohns committed Aug 23, 2023
1 parent 0e4f16e commit f2fecbf
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 12 deletions.
2 changes: 1 addition & 1 deletion InterSpec/QRSpectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ enum EncodeOptions
For example, a returned URI will start with:
"mailto:user@example.com?subject=spectrum&body=Spectrum%20URI%0D%0Araddata:..."
and it will not be stricktly URL encoded.
and it will not be strictly URL encoded.
*/
AsMailToUri = 0x20,
};//enum EncodeOptions
Expand Down
11 changes: 6 additions & 5 deletions src/QRSpectrum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1445,7 +1445,7 @@ vector<string> url_encode_spectrum( const UrlSpectrum &m,
}//if( use_baseX_encoding || (!use_deflate && !use_bin_chan_data) )


if( !skip_encoding && (use_url_safe_base64 || (!use_deflate && !use_bin_chan_data)) )
if( !skip_encoding && use_url_safe_base64 )
{
for( const string &url : answer )
{
Expand Down Expand Up @@ -2024,21 +2024,22 @@ EncodedSpectraInfo get_spectrum_url_info( std::string url )
| EncodeOptions::CsvChannelData | EncodeOptions::NoZeroCompressCounts
| EncodeOptions::UseUrlSafeBase64 | EncodeOptions::AsMailToUri) )
{
throw runtime_error( string("Encoding option had invalid bit set (hex digit ") + url[0] + ")" );
throw runtime_error( string("Encoding option had invalid bit set (hex digit ")
+ url[0] + (has_email_opt ? (string() + url[1]) : string()) + ")" );
}

answer.m_number_urls = hex_to_dec( url[1] ) + 1;
answer.m_number_urls = hex_to_dec( url[(has_email_opt ? 2 : 1)] ) + 1;
if( answer.m_number_urls > 10 )
throw std::runtime_error( "Invalid number of total URLs specified" );

if( answer.m_number_urls > 1 )
{
answer.m_spectrum_number = hex_to_dec( url[2] );
answer.m_spectrum_number = hex_to_dec( url[(has_email_opt ? 3 : 2)] );
if( answer.m_spectrum_number >= answer.m_number_urls )
throw runtime_error( "Spectrum number larger than total number URLs" );
}else
{
answer.m_num_spectra = hex_to_dec( url[2] ) + 1;
answer.m_num_spectra = hex_to_dec( url[(has_email_opt ? 3 : 2)] ) + 1;
if( answer.m_num_spectra > 10 )
throw std::runtime_error( "Invalid number of spectra in URL." );
}
Expand Down
69 changes: 63 additions & 6 deletions target/testing/test_QrSpectrum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,21 +136,39 @@ BOOST_AUTO_TEST_CASE( TestEncodeOptions )
const uint8_t encode_opts[] = {
0x00,
EncodeOptions::NoDeflate,
EncodeOptions::NoBase45,
EncodeOptions::NoBaseXEncoding,
EncodeOptions::CsvChannelData,
EncodeOptions::NoZeroCompressCounts,
EncodeOptions::NoZeroCompressCounts | EncodeOptions::CsvChannelData,
EncodeOptions::NoDeflate | EncodeOptions::NoBase45,
EncodeOptions::NoDeflate | EncodeOptions::NoBase45 | EncodeOptions::CsvChannelData,
EncodeOptions::NoDeflate | EncodeOptions::NoBase45 | EncodeOptions::CsvChannelData | EncodeOptions::NoZeroCompressCounts,
EncodeOptions::NoDeflate | EncodeOptions::NoBaseXEncoding,
EncodeOptions::NoDeflate | EncodeOptions::NoBaseXEncoding | EncodeOptions::CsvChannelData,
EncodeOptions::NoDeflate | EncodeOptions::NoBaseXEncoding | EncodeOptions::CsvChannelData | EncodeOptions::NoZeroCompressCounts,
EncodeOptions::UseUrlSafeBase64,
EncodeOptions::NoDeflate | EncodeOptions::UseUrlSafeBase64,
EncodeOptions::CsvChannelData | EncodeOptions::UseUrlSafeBase64,
EncodeOptions::NoZeroCompressCounts | EncodeOptions::CsvChannelData | EncodeOptions::UseUrlSafeBase64,
EncodeOptions::AsMailToUri,
//EncodeOptions::AsMailToUri | EncodeOptions::UseUrlSafeBase64,
};

for( const uint8_t encode_options : encode_opts )
{
const vector<UrlEncodedSpec> encoded = url_encode_spectra( {spec}, QrErrorCorrection::High, encode_options);
BOOST_REQUIRE( encoded.size() == 1 );

const vector<UrlSpectrum> decoded = decode_spectrum_urls( { Wt::Utils::urlDecode( encoded[0].m_url ) } );
string uri = encoded[0].m_url;

if( encode_options & EncodeOptions::AsMailToUri )
{
size_t pos = uri.find( "raddata://" );
if( pos == string::npos )
pos = uri.find( "RADDATA://" );
BOOST_REQUIRE( pos != string::npos );
uri = uri.substr( pos );
uri = Wt::Utils::urlDecode( uri );
}

const vector<UrlSpectrum> decoded = decode_spectrum_urls( { Wt::Utils::urlDecode( uri ) } );
BOOST_REQUIRE( decoded.size() == 1 );

test_equalish( spec, decoded[0], true );
Expand All @@ -172,7 +190,7 @@ BOOST_AUTO_TEST_CASE( TestNonAsciiTitleAndModelStrings )
// Check standard encoding, and also when the strings should be URL encoded at time of forming URL (which will then be encoded again)
const uint8_t encode_opts[] = {
0x0,
EncodeOptions::NoDeflate | EncodeOptions::NoBase45 | EncodeOptions::CsvChannelData
EncodeOptions::NoDeflate | EncodeOptions::NoBaseXEncoding | EncodeOptions::CsvChannelData
};

for( const uint8_t encode_options : encode_opts )
Expand Down Expand Up @@ -277,6 +295,45 @@ BOOST_AUTO_TEST_CASE( TwoSpectrumEncode )
}//BOOST_AUTO_TEST_CASE( TwoSpectrumEncode )


BOOST_AUTO_TEST_CASE( base64url_encoding )
{
BOOST_CHECK( base64url_encode("HelloWorld",true) == "SGVsbG9Xb3JsZA==" );
BOOST_CHECK( base64url_encode("HelloWorld",false) == "SGVsbG9Xb3JsZA" );

BOOST_CHECK( base64url_encode("0/?",false) == "MC8_" );
BOOST_CHECK( base64url_encode("0/?/\\}{_=+,",false) == "MC8_L1x9e189Kyw" );
BOOST_CHECK( base64url_encode("",false) == "" );


for( uint8_t i = 0x00; true ; ++i )
{
const char val = reinterpret_cast<char &>( i );
const string input( 3, val );
const string encode_output = base64url_encode( input, false );
BOOST_CHECK( encode_output.size() == 4 );
const vector<uint8_t> decode_output_bytes = base64url_decode( encode_output );
string decode_output( decode_output_bytes.size(), '\0' );
memcpy( &(decode_output[0]), &(decode_output_bytes[0]), decode_output_bytes.size() );
BOOST_CHECK( decode_output == input );

if( i == 255 )
break;
}//for( uint8_t i = 0x00; true ; ++i )

for( size_t trial = 0; trial < 1000; ++trial )
{
const size_t len = size_t(rand()) % 65535;
std::vector<uint8_t> input( len );
for( size_t i = 0; i < len; ++i )
input[i] = static_cast<uint8_t>( (rand() % 255) );

const string encode_output = base64url_encode( input, (rand() % 2) );
const vector<uint8_t> decode_output_bytes = base64url_decode( encode_output );
BOOST_CHECK( decode_output_bytes == input );
}//for( size_t i = 0; i < 1000; ++i )

}//BOOST_AUTO_TEST_CASE( base64url_encoding )


BOOST_AUTO_TEST_CASE( base45Encoding )
{
Expand Down

0 comments on commit f2fecbf

Please sign in to comment.