GeneratePlaceholderCanvasData.h (3243B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_GeneratePlaceholderCanvasData_h 8 #define mozilla_dom_GeneratePlaceholderCanvasData_h 9 10 #include "mozilla/StaticPrefs_privacy.h" 11 #include "nsCOMPtr.h" 12 #include "nsIRandomGenerator.h" 13 #include "nsServiceManagerUtils.h" 14 15 #define RANDOM_BYTES_TO_SAMPLE 32 16 17 namespace mozilla::dom { 18 19 /** 20 * This function tries to generate random data for placeholder canvas by 21 * sampling RANDOM_BYTES_TO_SAMPLE bytes and then returning it. If it fails, 22 * returns nullptr. 23 * 24 * @return uint8_t* output buffer 25 */ 26 inline uint8_t* TryToGenerateRandomDataForPlaceholderCanvasData() { 27 nsresult rv; 28 nsCOMPtr<nsIRandomGenerator> rg = 29 do_GetService("@mozilla.org/security/random-generator;1", &rv); 30 if (NS_FAILED(rv)) { 31 return nullptr; 32 } 33 uint8_t* randomData; 34 rv = rg->GenerateRandomBytes(RANDOM_BYTES_TO_SAMPLE, &randomData); 35 if (NS_FAILED(rv)) { 36 return nullptr; 37 } 38 return randomData; 39 } 40 41 /** 42 * If randomData not nullptr, repeats those bytes many times to fill buffer. If 43 * randomData is nullptr, returns all-white pixel data. 44 * 45 * @param[in] randomData Buffer of RANDOM_BYTES_TO_SAMPLE bytes of random 46 * data, or nullptr 47 * @param[in] size Size of output buffer 48 * @param[out] buffer Output buffer 49 */ 50 inline void FillPlaceholderCanvas(uint8_t* randomData, uint32_t size, 51 uint8_t* buffer) { 52 if (!randomData) { 53 memset(buffer, 0xFF, size); 54 return; 55 } 56 auto remaining_to_fill = size; 57 auto index = 0; 58 while (remaining_to_fill > 0) { 59 auto bytes_to_write = (remaining_to_fill > RANDOM_BYTES_TO_SAMPLE) 60 ? RANDOM_BYTES_TO_SAMPLE 61 : remaining_to_fill; 62 memcpy(buffer + (index * RANDOM_BYTES_TO_SAMPLE), randomData, 63 bytes_to_write); 64 remaining_to_fill -= bytes_to_write; 65 index++; 66 } 67 free(randomData); 68 } 69 70 /** 71 * When privacy.resistFingerprinting.randomDataOnCanvasExtract is true, tries 72 * to generate random canvas data by sampling RANDOM_BYTES_TO_SAMPLE bytes and 73 * then repeating those bytes many times to fill the buffer. If this fails or 74 * if privacy.resistFingerprinting.randomDataOnCanvasExtract is false, returns 75 * all-white, opaque pixel data. 76 * 77 * It is recommended that callers call this function instead of individually 78 * calling TryToGenerateRandomDataForPlaceholderCanvasData and 79 * FillPlaceholderCanvas unless there are requirements, like NoGC, that prevent 80 * them from calling the RNG service inside this function. 81 * 82 * @param[in] size Size of output buffer 83 * @param[out] buffer Output buffer 84 */ 85 inline void GeneratePlaceholderCanvasData(uint32_t size, uint8_t* buffer) { 86 uint8_t* randomData = TryToGenerateRandomDataForPlaceholderCanvasData(); 87 FillPlaceholderCanvas(randomData, size, buffer); 88 } 89 90 } // namespace mozilla::dom 91 92 #endif // mozilla_dom_GeneratePlaceholderCanvasData_h