Fix potential race-condition in reference scanning code
Previously the code ensures that the isBase32 array would only be initialised once in a single-threaded context. If two threads happen to call the function before the initialisation was completed both of them would have completed the initialization step. This allowed for a race-condition where one thread might be done with the initialization but the other thread sets all the fields to false again. For a brief moment the base32 detection would then produce false-negatives.
This commit is contained in:
parent
2b67cb7b8c
commit
b2d3976163
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -16,14 +17,13 @@ static unsigned int refLength = 32; /* characters */
|
||||||
static void search(const unsigned char * s, size_t len,
|
static void search(const unsigned char * s, size_t len,
|
||||||
StringSet & hashes, StringSet & seen)
|
StringSet & hashes, StringSet & seen)
|
||||||
{
|
{
|
||||||
static bool initialised = false;
|
static std::once_flag initialised;
|
||||||
static bool isBase32[256];
|
static bool isBase32[256];
|
||||||
if (!initialised) {
|
std::call_once(initialised, [](){
|
||||||
for (unsigned int i = 0; i < 256; ++i) isBase32[i] = false;
|
for (unsigned int i = 0; i < 256; ++i) isBase32[i] = false;
|
||||||
for (unsigned int i = 0; i < base32Chars.size(); ++i)
|
for (unsigned int i = 0; i < base32Chars.size(); ++i)
|
||||||
isBase32[(unsigned char) base32Chars[i]] = true;
|
isBase32[(unsigned char) base32Chars[i]] = true;
|
||||||
initialised = true;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i + refLength <= len; ) {
|
for (size_t i = 0; i + refLength <= len; ) {
|
||||||
int j;
|
int j;
|
||||||
|
|
Loading…
Reference in a new issue