From 6e6794786ae6f9a81281dd4467c834f70040b77c Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 21 Oct 2015 23:28:39 +0100 Subject: mnemonics: sanity checks for word lists and a test to go with it Remember to run the test when changing word lists, or simplewallet will throw uncaught if that word list is used. --- src/mnemonics/language_base.h | 29 ++++++++++++++++++++++++++--- src/mnemonics/old_english.h | 2 +- src/mnemonics/spanish.h | 2 +- 3 files changed, 28 insertions(+), 5 deletions(-) (limited to 'src/mnemonics') diff --git a/src/mnemonics/language_base.h b/src/mnemonics/language_base.h index c085a8b1d..8f0a7a9d3 100644 --- a/src/mnemonics/language_base.h +++ b/src/mnemonics/language_base.h @@ -38,6 +38,7 @@ #include #include #include +#include "misc_log_ex.h" /*! * \namespace Language @@ -73,6 +74,10 @@ namespace Language class Base { protected: + enum { + ALLOW_SHORT_WORDS = 1<<0, + ALLOW_DUPLICATE_PREFIXES = 1<<1, + }; const std::vector word_list; /*!< A pointer to the array of words */ std::unordered_map word_map; /*!< hash table to find word's index */ std::unordered_map trimmed_word_map; /*!< hash table to find word's trimmed index */ @@ -81,21 +86,39 @@ namespace Language /*! * \brief Populates the word maps after the list is ready. */ - void populate_maps() + void populate_maps(uint32_t flags = 0) { int ii; std::vector::const_iterator it; + if (word_list.size () != 1626) + throw std::runtime_error("Wrong word list length for " + language_name); for (it = word_list.begin(), ii = 0; it != word_list.end(); it++, ii++) { word_map[*it] = ii; + if ((*it).size() < unique_prefix_length) + { + if (flags & ALLOW_SHORT_WORDS) + MWARNING(language_name << " word '" << *it << "' is shorter than its prefix length, " << unique_prefix_length); + else + throw std::runtime_error("Too short word in " + language_name + " word list: " + *it); + } + std::string trimmed; if (it->length() > unique_prefix_length) { - trimmed_word_map[utf8prefix(*it, unique_prefix_length)] = ii; + trimmed = utf8prefix(*it, unique_prefix_length); } else { - trimmed_word_map[*it] = ii; + trimmed = *it; + } + if (trimmed_word_map.find(trimmed) != trimmed_word_map.end()) + { + if (flags & ALLOW_DUPLICATE_PREFIXES) + MWARNING("Duplicate prefix in " << language_name << " word list: " << trimmed); + else + throw std::runtime_error("Duplicate prefix in " + language_name + " word list: " + trimmed); } + trimmed_word_map[trimmed] = ii; } } public: diff --git a/src/mnemonics/old_english.h b/src/mnemonics/old_english.h index 1a96f4b1e..21ac95de3 100644 --- a/src/mnemonics/old_english.h +++ b/src/mnemonics/old_english.h @@ -1680,7 +1680,7 @@ namespace Language "weary" }), 4) { - populate_maps(); + populate_maps(ALLOW_DUPLICATE_PREFIXES | ALLOW_SHORT_WORDS); } }; } diff --git a/src/mnemonics/spanish.h b/src/mnemonics/spanish.h index a9a93243c..4b386a968 100644 --- a/src/mnemonics/spanish.h +++ b/src/mnemonics/spanish.h @@ -1680,7 +1680,7 @@ namespace Language "rito" }), 4) { - populate_maps(); + populate_maps(ALLOW_SHORT_WORDS); } }; } -- cgit v1.2.3