2121#include " app/rest/util.h"
2222#include " app/src/include/firebase/future.h"
2323#include " app/src/thread.h"
24- #include " app/src/util_desktop.h"
2524#include " auth/src/common.h"
2625#include " auth/src/data.h"
2726#include " auth/src/desktop/auth_data_handle.h"
@@ -412,6 +411,56 @@ void UserDataPersist::OnAuthStateChanged(Auth* auth) { // NOLINT
412411 }
413412}
414413
414+ static bool IsHexDigit (char c) {
415+ if (c >= ' 0' && c <= ' 9' ) return true ;
416+ if (c >= ' A' && c <= ' F' ) return true ;
417+ return false ;
418+ }
419+
420+ static uint8_t HexToValue (char digit) {
421+ if (digit >= ' 0' && digit <= ' 9' ) {
422+ return static_cast <uint8_t >(digit - ' 0' );
423+ }
424+ if (digit >= ' A' && digit <= ' F' ) {
425+ return 10 + static_cast <uint8_t >(digit - ' A' );
426+ }
427+ FIREBASE_ASSERT (" Not a hex digit" == nullptr );
428+ return 0 ;
429+ }
430+
431+ bool UserDataPersist::HexDecode (const std::string& encoded,
432+ std::string* decoded) {
433+ FIREBASE_ASSERT (decoded != nullptr );
434+ if (encoded.length () % 2 != 0 ) {
435+ *decoded = std::string ();
436+ return false ;
437+ }
438+ decoded->resize (encoded.length () / 2 );
439+ for (int i = 0 ; i < encoded.length (); i += 2 ) {
440+ char hi = toupper (encoded[i]);
441+ char lo = toupper (encoded[i + 1 ]);
442+ if (!IsHexDigit (hi) || !IsHexDigit (lo)) {
443+ *decoded = std::string ();
444+ return false ;
445+ }
446+ (*decoded)[i / 2 ] = (HexToValue (hi) << 4 ) | HexToValue (lo);
447+ }
448+ return true ;
449+ }
450+
451+ void UserDataPersist::HexEncode (const std::string& original,
452+ std::string* encoded) {
453+ FIREBASE_ASSERT (encoded != nullptr );
454+ encoded->resize (original.length () * 2 );
455+ for (int i = 0 ; i < encoded->length (); i += 2 ) {
456+ unsigned char value = original[i / 2 ];
457+ unsigned char hi = (value & 0xF0 ) >> 4 ;
458+ unsigned char lo = (value & 0x0F ) >> 0 ;
459+ (*encoded)[i + 0 ] = (hi < 10 ) ? (' 0' + hi) : (' A' + hi - 10 );
460+ (*encoded)[i + 1 ] = (lo < 10 ) ? (' 0' + lo) : (' A' + lo - 10 );
461+ }
462+ }
463+
415464void AssignLoadedData (const Future<std::string>& future, void * auth_data) {
416465 if (future.error () == secure::kNoEntry ) {
417466 LogDebug (future.error_message ());
@@ -425,7 +474,9 @@ void AssignLoadedData(const Future<std::string>& future, void* auth_data) {
425474
426475 // Decode to flatbuffer
427476 std::string decoded;
428- firebase::Base64Decode (loaded_string, &decoded);
477+ if (!UserDataPersist::HexDecode (loaded_string, &decoded)) {
478+ return ; // Invalid data.
479+ }
429480
430481 auto userData = GetUserDataDesktop (decoded.c_str ());
431482 if (userData != nullptr ) {
@@ -502,7 +553,7 @@ Future<void> UserDataPersist::SaveUserData(AuthData* auth_data) {
502553 save_string.assign (bufferpointer, bufferpointer + builder.GetSize ());
503554 // Encode flatbuffer
504555 std::string encoded;
505- firebase::Base64Encode (save_string, &encoded);
556+ HexEncode (save_string, &encoded);
506557
507558 return user_secure_manager_->SaveUserData (auth_data->app ->name (), encoded);
508559}
0 commit comments