diff --git a/toolkit/components/places/src/Helpers.cpp b/toolkit/components/places/src/Helpers.cpp index d7ac146b1a0..229f1db7bbb 100644 --- a/toolkit/components/places/src/Helpers.cpp +++ b/toolkit/components/places/src/Helpers.cpp @@ -38,9 +38,14 @@ #include "Helpers.h" #include "mozIStorageError.h" +#include "nsIRandomGenerator.h" +#include "plbase64.h" #include "nsString.h" #include "nsNavHistory.h" +// The length of guids that are used by history and bookmarks. +#define GUID_LENGTH 12 + namespace mozilla { namespace places { @@ -228,5 +233,54 @@ ReverseString(const nsString& aInput, nsString& aReversed) } } +static +nsresult +Base64urlEncode(const PRUint8* aBytes, + PRUint32 aNumBytes, + nsCString& _result) +{ + // SetLength does not set aside space for NULL termination. PL_Base64Encode + // will not NULL terminate, however, nsCStrings must be NULL terminated. As a + // result, we set the capacity to be one greater than what we need, and the + // length to our desired length. + PRUint32 length = (aNumBytes + 2) / 3 * 4; // +2 due to integer math. + NS_ENSURE_TRUE(_result.SetCapacity(length + 1), NS_ERROR_OUT_OF_MEMORY); + _result.SetLength(length); + (void)PL_Base64Encode(reinterpret_cast(aBytes), aNumBytes, + _result.BeginWriting()); + + // base64url encoding is defined in RFC 4648. It replaces the last two + // alphabet characters of base64 encoding with '-' and '_' respectively. + _result.ReplaceChar('+', '-'); + _result.ReplaceChar('/', '_'); + return NS_OK; +} + +nsresult +GenerateGUID(nsCString& _guid) +{ + _guid.Truncate(); + + // Request raw random bytes and base64url encode them. For each set of three + // bytes, we get one character. + const PRUint32 kRequiredBytesLength = + static_cast(GUID_LENGTH / 4 * 3); + + nsCOMPtr rg = + do_GetService("@mozilla.org/security/random-generator;1"); + NS_ENSURE_STATE(rg); + + PRUint8* buffer; + nsresult rv = rg->GenerateRandomBytes(kRequiredBytesLength, &buffer); + NS_ENSURE_SUCCESS(rv, rv); + + rv = Base64urlEncode(buffer, kRequiredBytesLength, _guid); + NS_Free(buffer); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ASSERTION(_guid.Length() == GUID_LENGTH, "GUID is not the right size!"); + return NS_OK; +} + } // namespace places } // namespace mozilla diff --git a/toolkit/components/places/src/Helpers.h b/toolkit/components/places/src/Helpers.h index d7d7a2aa448..29efd3df99e 100644 --- a/toolkit/components/places/src/Helpers.h +++ b/toolkit/components/places/src/Helpers.h @@ -200,6 +200,13 @@ void GetReversedHostname(const nsString& aForward, nsString& aRevHost); */ void ReverseString(const nsString& aInput, nsString& aReversed); +/** + * Generates an 12 character guid to be used by bookmark and history entries. + * + * @note This guid uses the characters a-z, A-Z, 0-9, '-', and '_'. + */ +nsresult GenerateGUID(nsCString& _guid); + /** * Used to finalize a statementCache on a specified thread. */