Package: spamprobe Version: 1.4d-15 Severity: normal Tags: patch upstream Following the lack of reaction (upstream or here) to my previous bug report (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1014201), I tried to interface spamprobe to MySQL (MariaDB) myself.
While I got it somewhat working, I hit some performance problems and a data corruption bug in MariaDB (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1015293), so I'm deferring this project to a later time. Anyway, in the process of doing so, I found some patches and had to write some myself for some minor issues (nothing to do with MySQL) that might be useful, e.g. when building spamprobe with newer compiler versions. Since upstream seems to be dead, the Debian package might be the best place to keep the patches for anyone interested, so you might want to include them. Series: warnings.patch spamprobe.patch strstream.patch random.patch
Description: Fixing warnings (-Wall -Wno-deprecated) Author: Mikhail T. (https://sourceforge.net/p/spamprobe/patches/9/) Index: spamprobe-1.4d/src/includes/FrequencyDB.h =================================================================== --- spamprobe-1.4d.orig/src/includes/FrequencyDB.h +++ spamprobe-1.4d/src/includes/FrequencyDB.h @@ -164,9 +164,9 @@ private: private: const DatabaseConfig *m_config; - Ptr<FrequencyDBImpl> m_db; bool m_isInterrupted; bool m_isBusy; + Ptr<FrequencyDBImpl> m_db; }; #endif // _FrequencyDB_h Index: spamprobe-1.4d/src/database/HashDataFile.h =================================================================== --- spamprobe-1.4d.orig/src/database/HashDataFile.h +++ spamprobe-1.4d/src/database/HashDataFile.h @@ -93,7 +93,7 @@ public: bool isReadOnly() const { - m_isReadOnly; + return m_isReadOnly; } int createMode() const Index: spamprobe-1.4d/src/includes/LRUCache.h =================================================================== --- spamprobe-1.4d.orig/src/includes/LRUCache.h +++ spamprobe-1.4d/src/includes/LRUCache.h @@ -212,8 +212,8 @@ private: private: int m_maxSize; - int m_lockedCount; int m_normalCount; + int m_lockedCount; ListType m_normalList; ListType m_lockedList; MapType m_index; Index: spamprobe-1.4d/src/includes/Ref.h =================================================================== --- spamprobe-1.4d.orig/src/includes/Ref.h +++ spamprobe-1.4d/src/includes/Ref.h @@ -70,7 +70,7 @@ public: protected: RefBase() - : m_ptr(0), m_count(0) + : m_count(0), m_ptr(0) { } Index: spamprobe-1.4d/src/database/FrequencyDBImpl_hash.cc =================================================================== --- spamprobe-1.4d.orig/src/database/FrequencyDBImpl_hash.cc +++ spamprobe-1.4d/src/database/FrequencyDBImpl_hash.cc @@ -199,7 +199,7 @@ string FrequencyDBImpl_hash::getWordForI return FrequencyDB::COUNT_WORD; } else { char buffer[128]; - sprintf(buffer, "I0x%08x", key); + sprintf(buffer, "I0x%08lx", key); return buffer; } } @@ -210,7 +210,7 @@ HashDataFile::ulong_t FrequencyDBImpl_ha if (word == FrequencyDB::COUNT_WORD) { // key not used for count } else if (starts_with(word, "I0x")) { - sscanf(word.c_str() + 3, "%x", &key); + sscanf(word.c_str() + 3, "%lx", &key); } else { key = hash_string(word); } Index: spamprobe-1.4d/src/database/HashDataFile.cc =================================================================== --- spamprobe-1.4d.orig/src/database/HashDataFile.cc +++ spamprobe-1.4d/src/database/HashDataFile.cc @@ -122,7 +122,7 @@ void HashDataFile::populateEmptyFile(int unsigned char zeros[SIZE_MULTIPLE * WordArray::ENTRY_SIZE]; WordArray::fillNullBuffer(zeros, SIZE_MULTIPLE); - for (int i = 0; i < m_indexLimit; i += SIZE_MULTIPLE) { + for (unsigned i = 0; i < m_indexLimit; i += SIZE_MULTIPLE) { ::write(fd, &zeros, min(m_indexLimit - i, (HashDataFile::ulong_t)SIZE_MULTIPLE) * WordArray::ENTRY_SIZE); } } @@ -269,7 +269,7 @@ bool HashDataFile::write(ulong_t key, assert(m_base); int index = computeIndexForKey(key); - for (int i = 0; i < m_divisor; ++i) { + for (unsigned i = 0; i < m_divisor; ++i) { ulong_t old_key = m_array.readKey(index); if (old_key == key || old_key == 0) { m_array.writeWord(index, key, word_data); @@ -310,7 +310,7 @@ bool HashDataFile::read(ulong_t key, ulong_t old_key = 0; int index = computeIndexForKey(key); - for (int i = 0; i < m_divisor; ++i) { + for (unsigned i = 0; i < m_divisor; ++i) { m_array.readWord(index, old_key, word_data); if (old_key == key) { // slot matches our key so return it's value @@ -333,7 +333,7 @@ void HashDataFile::copyHeadersToFile(Has { ulong_t key = 0; WordData word_data; - for (int i = 0; i < m_numHeaders; ++i) { + for (unsigned i = 0; i < m_numHeaders; ++i) { readRecord(i, key, word_data); file.writeRecord(i, key, word_data); } @@ -343,7 +343,7 @@ void HashDataFile::copyContentsToFile(Ha { ulong_t key = 0; WordData word_data; - for (int i = m_numHeaders; i < m_indexLimit; ++i) { + for (unsigned i = m_numHeaders; i < m_indexLimit; ++i) { readRecord(i, key, word_data); if (key != 0) { file.write(key, word_data); Index: spamprobe-1.4d/src/database/Message.cc =================================================================== --- spamprobe-1.4d.orig/src/database/Message.cc +++ spamprobe-1.4d/src/database/Message.cc @@ -115,7 +115,7 @@ void Message::addToken(const string &wor if (tok) { tok->incrementCount(); m_tokensInOrder.push_back(tok); - } else if (m_maxTokenCount <= 0 || m_tokensByName.size() < m_maxTokenCount) { + } else if (m_maxTokenCount <= 0 || m_tokensByName.size() < (unsigned long)m_maxTokenCount) { tok = new Token(word, flags); m_tokensByIndex.push_back(tok); m_tokensByName.insert(make_pair(word, tok)); Index: spamprobe-1.4d/src/includes/Buffer.h =================================================================== --- spamprobe-1.4d.orig/src/includes/Buffer.h +++ spamprobe-1.4d/src/includes/Buffer.h @@ -42,9 +42,9 @@ class Buffer { public: explicit Buffer(int capacity) - : m_length(0), - m_capacity(capacity), - m_ptr(new T[capacity]) + : m_ptr(new T[capacity]), + m_length(0), + m_capacity(capacity) { assert(capacity > 0); } Index: spamprobe-1.4d/src/input/SimpleMultiLineStringCharReader.cc =================================================================== --- spamprobe-1.4d.orig/src/input/SimpleMultiLineStringCharReader.cc +++ spamprobe-1.4d/src/input/SimpleMultiLineStringCharReader.cc @@ -36,8 +36,8 @@ class SimpleMultiLineStringCharReaderPos public: SimpleMultiLineStringCharReaderPosition(const string *terminator, const AbstractMultiLineString *target) - : m_terminator(terminator), - m_target(target) + : m_target(target), + m_terminator(terminator) { assert(m_terminator); assert(m_target); Index: spamprobe-1.4d/src/input/StringReader.cc =================================================================== --- spamprobe-1.4d.orig/src/input/StringReader.cc +++ spamprobe-1.4d/src/input/StringReader.cc @@ -60,22 +60,22 @@ bool StringReader::forward() bool StringReader::hasChar() { - return m_index >= 0 && m_index < m_source.length(); + return m_index >= 0 && (unsigned)m_index < m_source.length(); } bool StringReader::skip(int nchars) { m_index += nchars; - if (m_index >= m_source.length()) { + if ((unsigned)m_index >= m_source.length()) { return false; } setCurrentChar(m_source[m_index]); - return m_index < m_source.length(); + return (unsigned)m_index < m_source.length(); } bool StringReader::atEnd() { - return m_index >= m_source.length(); + return (unsigned)m_index >= m_source.length(); } OWNED AbstractCharReaderPosition *StringReader::createMark() Index: spamprobe-1.4d/src/parser/GifParser.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/GifParser.cc +++ spamprobe-1.4d/src/parser/GifParser.cc @@ -94,6 +94,7 @@ bool GifParser::parseImage() } catch (runtime_error &ex) { return false; } + return true; } void GifParser::openImage() Index: spamprobe-1.4d/src/parser/MailMessage.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/MailMessage.cc +++ spamprobe-1.4d/src/parser/MailMessage.cc @@ -40,6 +40,7 @@ static const string IS_HTML_REGEX("<!|</?html>|<p>|<br/?>|</?tr>|</?td>|</?font |</?b>|<a "); +#if 0 static void dump(MailMessage *msg) { cerr << "PARSING MESSAGE: " << endl; @@ -50,6 +51,7 @@ static void dump(MailMessage *msg) cerr << "BODY: '" << msg->bodyText()->line(i) << "'" << endl; } } +#endif MailMessage::MailMessage(const CRef<AbstractMultiLineString> &full_text) : m_fullText(full_text) Index: spamprobe-1.4d/src/parser/MbxMailMessageReader.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/MbxMailMessageReader.cc +++ spamprobe-1.4d/src/parser/MbxMailMessageReader.cc @@ -54,8 +54,7 @@ MbxMailMessageReader::~MbxMailMessageRea bool MbxMailMessageReader::readMBXRecordHeader() { - bool again = true; - while (again) { + for (;;) { m_recordLength = 0; if (!reader()->hasLine()) { return false; Index: spamprobe-1.4d/src/parser/MessageHeaderList.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/MessageHeaderList.cc +++ spamprobe-1.4d/src/parser/MessageHeaderList.cc @@ -39,7 +39,7 @@ static const string CONTENT_TYPE("conten CRef<AbstractMultiLineString> MessageHeaderList::header(const string &name) const { MultiLineStringList values; - for (int i = 0; i < m_headers.size(); ++i) { + for (unsigned i = 0; i < m_headers.size(); ++i) { if (m_headers[i]->hasName(name)) { values.push_back(m_headers[i]->lines()); } Index: spamprobe-1.4d/src/parser/MimeDecoder.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/MimeDecoder.cc +++ spamprobe-1.4d/src/parser/MimeDecoder.cc @@ -71,7 +71,7 @@ static const int BASE64_CHARS[256] = { -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, }; -static const int MAX_CHAR_INDEX = sizeof(BASE64_CHARS) / sizeof(BASE64_CHARS[0]); +static const unsigned MAX_CHAR_INDEX = sizeof(BASE64_CHARS) / sizeof(BASE64_CHARS[0]); inline bool next_char64(AbstractCharReader *reader, char &ch, @@ -222,9 +222,9 @@ CRef<AbstractMultiLineString> MimeDecode bool add_new_line = true; const string &line(messageBody->line(k)); const char *line_chars = line.c_str(); - const int line_length = line.length(); - const int last_index = line_length - 1; - const int hex_limit = line_length - 2; + const string::size_type line_length = line.length(); + const string::size_type last_index = line_length - 1; + const string::size_type hex_limit = line_length - 2; for (string::size_type i = 0; i < line_length; ++i) { char ch = line_chars[i]; if (ch == '=') { Index: spamprobe-1.4d/src/parser/ParserConfig.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/ParserConfig.cc +++ spamprobe-1.4d/src/parser/ParserConfig.cc @@ -39,12 +39,12 @@ ParserConfig::ParserConfig() m_removeHTML(true), m_keepSuspiciousTags(false), m_ignoreBody(false), + m_spamprobeFieldName("x-spamprobe"), m_minPhraseTerms(1), m_maxPhraseTerms(2), m_minPhraseChars(0), m_maxPhraseChars(0), - m_maxTermsPerMessage(0), - m_spamprobeFieldName("x-spamprobe") + m_maxTermsPerMessage(0) { #ifdef USE_8BIT setReplaceNonAsciiChars(0); Index: spamprobe-1.4d/src/parser/PhrasingTokenizer.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/PhrasingTokenizer.cc +++ spamprobe-1.4d/src/parser/PhrasingTokenizer.cc @@ -86,7 +86,7 @@ void PhrasingTokenizer::compactChars() void PhrasingTokenizer::receiveToken(const string &prefix, const string &token) { - while (m_offsets.size() >= m_maxWordsInList) { + while (m_offsets.size() >= (unsigned)m_maxWordsInList) { m_offsets.pop_back(); } compactChars(); @@ -99,10 +99,10 @@ void PhrasingTokenizer::receiveToken(con assert(*i < m_chars.length()); const char *phrase = m_chars.c_str() + *i; string::size_type phrase_length = m_chars.length() - *i; - if (m_maxCharLength > 0 && phrase_length > m_maxCharLength) { + if (m_maxCharLength > 0 && phrase_length > (string::size_type)m_maxCharLength) { break; } - if ((num_words > m_maxWords) && (m_minCharLength <= 0 || phrase_length > m_minCharLength)) { + if ((num_words > m_maxWords) && (m_minCharLength <= 0 || phrase_length > (string::size_type)m_minCharLength)) { break; } if (num_words >= m_minWords) { Index: spamprobe-1.4d/src/parser/PngParser.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/PngParser.cc +++ spamprobe-1.4d/src/parser/PngParser.cc @@ -76,6 +76,7 @@ bool PngParser::parseImage() } catch (runtime_error &ex) { return false; } + return true; } void PngParser::initializeImage() Index: spamprobe-1.4d/src/parser/TokenFilteringTokenizer.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/TokenFilteringTokenizer.cc +++ spamprobe-1.4d/src/parser/TokenFilteringTokenizer.cc @@ -37,7 +37,7 @@ TokenFilteringTokenizer::TokenFilteringT int min_length, int max_length, bool allow_numbers) -: m_tokenizer(tokenizer), m_minLength(min_length), m_maxLength(max_length), m_allowNumbers(allow_numbers) +: m_minLength(min_length), m_maxLength(max_length), m_allowNumbers(allow_numbers), m_tokenizer(tokenizer) { } @@ -48,11 +48,11 @@ TokenFilteringTokenizer::~TokenFiltering void TokenFilteringTokenizer::receiveToken(const string &prefix, const string &token) { - if (token.length() < m_minLength) { + if (token.length() < (unsigned)m_minLength) { return; } - if (token.length() > m_maxLength) { + if (token.length() > (unsigned)m_maxLength) { return; } Index: spamprobe-1.4d/src/parser/TraditionalMailMessageParser.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/TraditionalMailMessageParser.cc +++ spamprobe-1.4d/src/parser/TraditionalMailMessageParser.cc @@ -54,8 +54,8 @@ static const string IP_ADDRESS_TERM("IP_ static const string LINE_SEPARATOR(" "); TraditionalMailMessageParser::TraditionalMailMessageParser(ParserConfig *config) - : m_config(config), - m_ipRegex(IP_ADDRESS_REGEX) + : m_ipRegex(IP_ADDRESS_REGEX), + m_config(config) { } Index: spamprobe-1.4d/src/utility/MD5Digester.cc =================================================================== --- spamprobe-1.4d.orig/src/utility/MD5Digester.cc +++ spamprobe-1.4d/src/utility/MD5Digester.cc @@ -32,8 +32,8 @@ #include "MD5Digester.h" MD5Digester::MD5Digester() - : m_running(false), - m_state(new md5_state_s) + : m_state(new md5_state_s), + m_running(false) { } Index: spamprobe-1.4d/src/hdl/HdlStandardStatementConstraint.cc =================================================================== --- spamprobe-1.4d.orig/src/hdl/HdlStandardStatementConstraint.cc +++ spamprobe-1.4d/src/hdl/HdlStandardStatementConstraint.cc @@ -63,7 +63,7 @@ void HdlStandardStatementConstraint::val } if (stmt->numArguments() > m_minArgCount) { - if (m_minArgCount > 0 && m_minArgCount >= m_arguments.size()) { + if (m_minArgCount > 0 && (unsigned)m_minArgCount >= m_arguments.size()) { cerr << "m_minArgCount: " << m_minArgCount << endl; cerr << "num_args " << m_arguments.size() << endl; throw HdlError("internal error: insufficient argument definitions", stmt->name()); Index: spamprobe-1.4d/src/hdl/HdlSyntaxChecker.cc =================================================================== --- spamprobe-1.4d.orig/src/hdl/HdlSyntaxChecker.cc +++ spamprobe-1.4d/src/hdl/HdlSyntaxChecker.cc @@ -162,7 +162,6 @@ int HdlSyntaxChecker::parseArgs(const Re void HdlSyntaxChecker::parseTable(const Ref<HdlArgumentConstraint> &table, const CRef<HdlStatement> &stmt) { - int id_index = 0; for (int i = 0; i < stmt->numArguments(); ++i) { const CRef<HdlToken> &token = stmt->argument(i); if (token->strValue() == "string") { Index: spamprobe-1.4d/src/spamprobe/AbstractMessageCommand.cc =================================================================== --- spamprobe-1.4d.orig/src/spamprobe/AbstractMessageCommand.cc +++ spamprobe-1.4d/src/spamprobe/AbstractMessageCommand.cc @@ -74,7 +74,6 @@ void AbstractMessageCommand::processMail const File *stream_file, Ptr<AbstractMailMessageReader> &mail_reader) { - const CommandConfig *cmd_config = config.commandConfig(); const ParserConfig *prs_config = config.parserConfig(); TraditionalMailMessageParser parser(config.parserConfig()); Index: spamprobe-1.4d/src/spamprobe/Command_auto_train.cc =================================================================== --- spamprobe-1.4d.orig/src/spamprobe/Command_auto_train.cc +++ spamprobe-1.4d/src/spamprobe/Command_auto_train.cc @@ -177,7 +177,6 @@ int Command_auto_train::execute(const Co spam_command = Command_spam::createTrainSpamCommand(); } - bool is_message_spam = false; int message_num = 0; ParserConfig *parser_config = config.parserConfig(); @@ -186,7 +185,6 @@ int Command_auto_train::execute(const Co MailMessageDigester digester; AutoPurger purger(config, filter); - int cumulative_message_count = 0; Ptr<MailMessage> mail_message; mail_message.set(mail_reader->readMessage()); while (mail_message.isNotNull()) { @@ -198,7 +196,6 @@ int Command_auto_train::execute(const Co if (should_log) { score = filter.scoreMessage(*msg); } - bool scored_as_spam = should_log && filter.scoreMessage(*msg).isSpam(); bool is_spam = mail_reader->messageWasSpam(); if (should_log) { logMessage(config, filter, is_spam ? "SPAM" : "GOOD", score.isSpam() == is_spam, *msg); Index: spamprobe-1.4d/src/spamprobe/FilterConfig.cc =================================================================== --- spamprobe-1.4d.orig/src/spamprobe/FilterConfig.cc +++ spamprobe-1.4d/src/spamprobe/FilterConfig.cc @@ -32,8 +32,8 @@ #include "FilterConfig.h" FilterConfig::FilterConfig() - : m_termsForScore(27), - m_defaultMinWordCount(5), + : m_defaultMinWordCount(5), + m_termsForScore(27), m_maxWordRepeats(2), m_extendTopTerms(false), m_newWordScore(0.3),
Description: spamprobe crashes when parsing jpeg mime attachment Author: Torsten Hilbrich (https://sourceforge.net/p/spamprobe/bugs/39/) Index: spamprobe-1.4d/src/parser/GifParser.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/GifParser.cc +++ spamprobe-1.4d/src/parser/GifParser.cc @@ -91,6 +91,7 @@ bool GifParser::parseImage() openImage(); digestImage(); parseImageRecords(); + return true; } catch (runtime_error &ex) { return false; } Index: spamprobe-1.4d/src/parser/JpegParser.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/JpegParser.cc +++ spamprobe-1.4d/src/parser/JpegParser.cc @@ -61,6 +61,7 @@ bool JpegParser::parseImage() initializeSource(); digestImage(); tokenizeImage(); + return true; } catch (runtime_error &ex) { return false; } Index: spamprobe-1.4d/src/parser/MbxMailMessageReader.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/MbxMailMessageReader.cc +++ spamprobe-1.4d/src/parser/MbxMailMessageReader.cc @@ -85,6 +85,7 @@ bool MbxMailMessageReader::readMBXRecord cerr << "MBX: SKIPPED DELETED MESSAGE" << endl; } } + return true; } OWNED MailMessage *MbxMailMessageReader::readMessage() Index: spamprobe-1.4d/src/parser/PngParser.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/PngParser.cc +++ spamprobe-1.4d/src/parser/PngParser.cc @@ -73,6 +73,7 @@ bool PngParser::parseImage() try { digestImage(); initializeImage(); + return true; } catch (runtime_error &ex) { return false; }
Description: Avoid deprecated strstream Author: Frank Heckenbach <f.heckenb...@fh-soft.de> Index: spamprobe-1.4d/src/database/FrequencyDBImpl_bdb.cc =================================================================== --- spamprobe-1.4d.orig/src/database/FrequencyDBImpl_bdb.cc +++ spamprobe-1.4d/src/database/FrequencyDBImpl_bdb.cc @@ -32,7 +32,7 @@ #include <unistd.h> #include <stdexcept> -#include <strstream> +#include <sstream> #include "CleanupManager.h" #include "LockFile.h" #include "WordData.h" @@ -67,10 +67,9 @@ inline int throw_on_error(const char *fu return rc; } if (rc != 0) { - static char buffer[4096]; - ostrstream msg(buffer, sizeof(buffer)); + ostringstream msg; msg << function_name << ": " << db_strerror(rc) << " (" << rc << ")" << ends; - throw runtime_error(buffer); + throw runtime_error(msg.str()); } return rc; } Index: spamprobe-1.4d/src/database/FrequencyDBImpl_pbl.cc =================================================================== --- spamprobe-1.4d.orig/src/database/FrequencyDBImpl_pbl.cc +++ spamprobe-1.4d/src/database/FrequencyDBImpl_pbl.cc @@ -32,7 +32,7 @@ #include <unistd.h> #include <fcntl.h> -#include <strstream> +#include <sstream> #include <stdexcept> #include "CleanupManager.h" #include "LockFile.h" @@ -55,10 +55,9 @@ inline int throw_on_error(const char *fu return PBL_ERROR_NOT_FOUND; } - static char buffer[4096]; - ostrstream msg(buffer, sizeof(buffer)); + ostringstream msg; msg << function_name << ": " << pbl_errstr << " (" << pbl_errno << ")" << ends; - throw runtime_error(buffer); + throw runtime_error(msg.str()); } inline int warn_on_error(const char *function_name,
Description: use reproducible pseudo-random numbers in AutoTrainMailMessageReader Author: Frank Heckenbach <f.heckenb...@fh-soft.de> Index: spamprobe-1.4d/src/parser/AutoTrainMailMessageReader.cc =================================================================== --- spamprobe-1.4d.orig/src/parser/AutoTrainMailMessageReader.cc +++ spamprobe-1.4d/src/parser/AutoTrainMailMessageReader.cc @@ -29,6 +29,7 @@ // #include <cstdlib> +#include <random> #include "MailMessage.h" #include "AutoTrainMailMessageReader.h" @@ -140,5 +141,15 @@ OWNED MailMessage *AutoTrainMailMessageR bool AutoTrainMailMessageReader::shouldUseSpam() { - return (m_totalCount >= 0) && ((random() % m_totalCount) < m_spamCount); + /* The original code uses "random" here without seeding it. + But some DB backends (e.g. BDB) seed the PRNG internally. + This gives the worst of both worlds: No real randomness, + yet different results with different backends which makes + it hard to compare them for performance or correctness. + Now, this uses a separate PRNG and leaves it unseeded, + to make results comparable, at the cost of no real + randomness which does not seem so important here. */ + static mt19937 PRNG; + uniform_int_distribution<mt19937::result_type> dist(0, m_totalCount - 1); + return (m_totalCount >= 0) && (dist(PRNG) < m_spamCount); }