1
0
forked from cheng/wallet
wallet/src/localization.cpp
Cheng 61db535769
user friendly error handling of zooko names
Fixed it while dead drunk
could not walk in a straight line
had difficulty typing
coded rather slowly, but still wrote
smart code.

Realized that the error handling
has to have exception structures in
scope, but not the constructors in
scope

You can forward the constructors,
but if you forward the structs,
exceptions will crash.  Your exception
constructor inputs can use structs that
are out of scope at the exception handler
2023-02-26 09:12:31 +08:00

478 lines
28 KiB
C++

// Everything that will need translation should be in localization.cpp
// But this task is barely begun, there are no end of English language
// strings strewn at random about the program which need to be moved to
// localization.h and localization.cpp
// Microsoft Windows, the Visual Studio Compiler, wxWidgets,
// and C++17 onwards is layer after layer of workarounds for the
// localization problem. Mutually conflicting workarounds that
// keep fouling each other up. The final solution to these problems
// is utf-8 and UTF16, and to make it work, you need wallet.manifest
// which gives you a UTF8 execution environment on program launch,
// as if we set the code page in the registry to
// Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage 65001
// Instead of its normal value of 1252
// and the /utf-8 compile option,
// Properties/C++/AdditionalOptions /utf-8
// which gives you a utf-8 compilation and code generation environment.
// with utf8 in effect at all three levels
// wxUSE_UNSAFE_WXSTRING_CONV == 1
// is desirable, because all those automagical string conversions
// will no longer bite you.
// We really should be running with wxUSE_UTF8_LOCALE_ONLY and
// wxUSE_UNICODE_UTF8, but this will require a wholesale rewrite of
// wxWidgets to use the windowsA calls rather than the windowsW calls,
// albeit this could largely be accomplished by redefining the windows
// macros to default to windowsA where at present they default to windowsW
#include <string>
#include "ILog.h"
#include "localization.h"
// I intend that the download pages will in a location related to the git
// repository, and that when we support multiple languages, the end user will
// download the executable for his language, that we will build a complete
// executable and complete install for every language supported.
// Since the network environment is utf-8, if the locale is not utf-8
// your program has to keep track of two kinds of strings, which it
// will not do successfully. So, forcing environment to utf with
// a windows manifest and a unit test environment check.
// Nearly all of these strings, all of them right now, are seven bit ascii,
// so unicode does not matter but it did a short time ago, and when we get
// around to localization, providing several versions of the localization
// file in several languages, it will matter again.
// No intent to support non UTF-8 locales anywhere in the code.
// code is intentionally written to break on such locales.
// No intent to support local date formats.
// All dates and times shall be YYYY-MM-DD_HH:mm:ss (international format)
// Local date formats are always ambiguous. Date localization is dangerous
// in a program intended to support promises and contracts.
/*
Intended usage is that we have a different download, a different
separately compiled complete program for every locale, with a different
locale.cpp file and all the other files unchanged, rather than trying
to make a single compiled program work in a variety of locales.
At present, there is only one locale.cpp, and if you have a better
solution for supporting multiple locales, you are probably better
qualified at supporting multiple locales than I am.
However my experience is that all the terribly clever solutions for
supporting multiple locales with a single compiled program are fragile
and break every time they issue a new skew of the operating system.
I don't trust them, and are not interested in learning about them.*/
//Menu strings
static const char * file_menu_strings[][2]{
{"&New wallet...", "New wallet file From new secret"},
{"Existing secret...","New Wallet File From the secret of an old wallet"},
{"&Open existing wallet file...",""},
{nullptr,"Close"},
{"&Reset defaults","Delete config file"}};
const menu_string menu_strings_[]{
{"&File", file_menu_strings},
{"&Edit", nullptr},
{"&Help", nullptr} };
const menu_string* menu_strings{ menu_strings_ };
// Strings for the startup display, load existing wallet or create new
// wallet.
const char sz_NewWallet[] {R"|(New Wallet)|"};
const char sz_new_wallet[] {R"|(new wallet)|"};
const char sz_unit_test_log[] { "log of unit test" };
const char sz_welcome_to_rocoin[] {R"|(Welcome to Rhocoin)|"};
const char sz_please_select_from_three_options[]{
R"|(Please select one of the following three options:)|"
};
const char sz_create_a_new_wallet[]{R"|(Create a new wallet)|"};
const char sz_recreate_wallet_from_old_secret[]{
R"|(Recreate a wallet from an old wallet's secret)|"
};
const char sz_existing_secret[] {R"|(existing secret)|" };
const char sz_open_existing_wallet[]{R"|(Open an existing wallet)|"};
const char sz_existing_wallet[] {R"|(existing wallet)|"};
const char sz_text_buffer_overflow[]{R"|(conversion to base64 would overflow text buffer)|"};
const char sz_unknown_error[]{ R"|(unknown error.)|"};
const char szAboutWallet[]{ R"|(A completely useless wallet
that is not even in a fit state for anyone else to work on)|" };
const char szAboutTitle[]{ R"|(About Wallet)|" };
//Error message strings
const wchar_t wsz_error[] { L"Error" };
const wchar_t wsz_operation[] { L"Operation aborted.\n" };
const wchar_t wsz_program[]{ L"The program will terminate.\n" };
//Command line parameters
const wchar_t wsz_commandLineLogo[]{LR"(rho wallet
for secure communication and crypto currency transfers inside secure communication)"};
const wchar_t wsz_usageText[]{ LR"(
Typical usage is: wallet
Subcommands are described in docs/wallet_subcommands.html)" };
// Strings for the self test are not represented here, though they probably
// should be.
FatalException::FatalException() noexcept :
MyException(R"|(unspecified fatal exception)|") {};
HashReuseException::HashReuseException() noexcept :
MyException(R"|(finalized the same hash constructor twice or more)|") {};
BadDataException::BadDataException() noexcept :
MyException(R"|(Bad data exception)|") {};
NonUtf8DataInDatabase::NonUtf8DataInDatabase() noexcept :
MyException(R"|(utf8 string in database is invalid utf8)|") {};
NonRandomScalarException::NonRandomScalarException() noexcept :
MyException(R"|(Not a random scalar, something insecure is going on)|") {};
BadScalarException::BadScalarException() noexcept :
MyException(R"|(Invalid scalar)|") {};
BadStringRepresentationOfCryptoIdException::BadStringRepresentationOfCryptoIdException() noexcept :
MyException(R"|(Invalid string representation of a cryptographic identifier)|") {};
NotBase58Exception::NotBase58Exception() noexcept :
MyException(R"|(Expected a base 58 character)|") {};
OversizeBase58String::OversizeBase58String() noexcept :
MyException(R"|(Too long)|") {};
const char FailureToThrowExpectedException_sz[]{ "Exception not thrown for deliberate error in unit test" };
// Random words for the passphrase.
// They should be replaced, rather than translated,
// with random short memorable words whose first characters
// are distinct.
const char* const ar_sz_bip_0039_wordlist[]{
"abandon", "ability", "able", "about", "above", "absent", "absorb",
"abstract", "absurd", "abuse", "access", "accident", "account",
"accuse", "achieve", "acid", "acoustic", "acquire", "across", "act",
"action", "actor", "actress", "actual", "adapt", "add", "addict",
"address", "adjust", "admit", "adult", "advance", "advice", "aerobic",
"affair", "afford", "afraid", "again", "age", "agent", "agree", "ahead",
"aim", "air", "airport", "aisle", "alarm", "album", "alcohol", "alert",
"alien", "all", "alley", "allow", "almost", "alone", "alpha", "already",
"also", "alter", "always", "amateur", "amazing", "among", "amount", "amused",
"analyst", "anchor", "ancient", "anger", "angle", "angry", "animal", "ankle",
"announce", "annual", "another", "answer", "antenna", "antique", "anxiety",
"any", "apart", "apology", "appear", "apple", "approve", "april", "arch",
"arctic", "area", "arena", "argue", "arm", "armed", "armor", "army", "around",
"arrange", "arrest", "arrive", "arrow", "art", "artefact", "artist", "artwork", "ask",
"aspect", "assault", "asset", "assist", "assume", "asthma", "athlete", "atom", "attack",
"attend", "attitude", "attract", "auction", "audit", "august", "aunt", "author", "auto",
"autumn", "average", "avocado", "avoid", "awake", "aware", "away", "awesome", "awful",
"awkward", "axis", "baby", "bachelor", "bacon", "badge", "bag", "balance", "balcony",
"ball", "bamboo", "banana", "banner", "bar", "barely", "bargain", "barrel", "base",
"basic", "basket", "battle", "beach", "bean", "beauty", "because", "become", "beef",
"before", "begin", "behave", "behind", "believe", "below", "belt", "bench", "benefit",
"best", "betray", "better", "between", "beyond", "bicycle", "bid", "bike", "bind",
"biology", "bird", "birth", "bitter", "black", "blade", "blame", "blanket", "blast",
"bleak", "bless", "blind", "blood", "blossom", "blouse", "blue", "blur", "blush",
"board", "boat", "body", "boil", "bomb", "bone", "bonus", "book", "boost",
"border", "boring", "borrow", "boss", "bottom", "bounce", "box", "boy", "bracket",
"brain", "brand", "brass", "brave", "bread", "breeze", "brick", "bridge", "brief",
"bright", "bring", "brisk", "broccoli", "broken", "bronze", "broom", "brother", "brown",
"brush", "bubble", "buddy", "budget", "buffalo", "build", "bulb", "bulk", "bullet",
"bundle", "bunker", "burden", "burger", "burst", "bus", "business", "busy", "butter",
"buyer", "buzz", "cabbage", "cabin", "cable", "cactus", "cage", "cake", "call",
"calm", "camera", "camp", "can", "canal", "cancel", "candy", "cannon", "canoe",
"canvas", "canyon", "capable", "capital", "captain", "car", "carbon", "card", "cargo",
"carpet", "carry", "cart", "case", "cash", "casino", "castle", "casual", "cat",
"catalog", "catch", "category", "cattle", "caught", "cause", "caution", "cave", "ceiling",
"celery", "cement", "census", "century", "cereal", "certain", "chair", "chalk", "champion",
"change", "chaos", "chapter", "charge", "chase", "chat", "cheap", "check", "cheese",
"chef", "cherry", "chest", "chicken", "chief", "child", "chimney", "choice", "choose",
"chronic", "chuckle", "chunk", "churn", "cigar", "cinnamon", "circle", "citizen", "city",
"civil", "claim", "clap", "clarify", "claw", "clay", "clean", "clerk", "clever",
"click", "client", "cliff", "climb", "clinic", "clip", "clock", "clog", "close",
"cloth", "cloud", "clown", "club", "clump", "cluster", "clutch", "coach", "coast",
"coconut", "code", "coffee", "coil", "coin", "collect", "color", "column", "combine",
"come", "comfort", "comic", "common", "company", "concert", "conduct", "confirm", "congress",
"connect", "consider", "control", "convince", "cook", "cool", "copper", "copy", "coral",
"core", "corn", "correct", "cost", "cotton", "couch", "country", "couple", "course",
"cousin", "cover", "coyote", "crack", "cradle", "craft", "cram", "crane", "crash",
"crater", "crawl", "crazy", "cream", "credit", "creek", "crew", "cricket", "crime",
"crisp", "critic", "crop", "cross", "crouch", "crowd", "crucial", "cruel", "cruise",
"crumble", "crunch", "crush", "cry", "crystal", "cube", "culture", "cup", "cupboard",
"curious", "current", "curtain", "curve", "cushion", "custom", "cute", "cycle", "dad",
"damage", "damp", "dance", "danger", "daring", "dash", "daughter", "dawn", "day",
"deal", "debate", "debris", "decade", "december", "decide", "decline", "decorate", "decrease",
"deer", "defense", "define", "defy", "degree", "delay", "deliver", "demand", "demise",
"denial", "dentist", "deny", "depart", "depend", "deposit", "depth", "deputy", "derive",
"describe", "desert", "design", "desk", "despair", "destroy", "detail", "detect", "develop",
"device", "devote", "diagram", "dial", "diamond", "diary", "dice", "diesel", "diet",
"differ", "digital", "dignity", "dilemma", "dinner", "dinosaur", "direct", "dirt", "disagree",
"discover", "disease", "dish", "dismiss", "disorder", "display", "distance", "divert", "divide",
"divorce", "dizzy", "doctor", "document", "dog", "doll", "dolphin", "domain", "donate",
"donkey", "donor", "door", "dose", "double", "dove", "draft", "dragon", "drama",
"drastic", "draw", "dream", "dress", "drift", "drill", "drink", "drip", "drive",
"drop", "drum", "dry", "duck", "dumb", "dune", "during", "dust", "dutch",
"duty", "dwarf", "dynamic", "eager", "eagle", "early", "earn", "earth", "easily",
"east", "easy", "echo", "ecology", "economy", "edge", "edit", "educate", "effort",
"egg", "eight", "either", "elbow", "elder", "electric", "elegant", "element", "elephant",
"elevator", "elite", "else", "embark", "embody", "embrace", "emerge", "emotion", "employ",
"empower", "empty", "enable", "enact", "end", "endless", "endorse", "enemy", "energy",
"enforce", "engage", "engine", "enhance", "enjoy", "enlist", "enough", "enrich", "enroll",
"ensure", "enter", "entire", "entry", "envelope", "episode", "equal", "equip", "era",
"erase", "erode", "erosion", "error", "erupt", "escape", "essay", "essence", "estate",
"eternal", "ethics", "evidence", "evil", "evoke", "evolve", "exact", "example", "excess",
"exchange", "excite", "exclude", "excuse", "execute", "exercise", "exhaust", "exhibit", "exile",
"exist", "exit", "exotic", "expand", "expect", "expire", "explain", "expose", "express",
"extend", "extra", "eye", "eyebrow", "fabric", "face", "faculty", "fade", "faint",
"faith", "fall", "false", "fame", "family", "famous", "fan", "fancy", "fantasy",
"farm", "fashion", "fat", "fatal", "father", "fatigue", "fault", "favorite", "feature",
"february", "federal", "fee", "feed", "feel", "female", "fence", "festival", "fetch",
"fever", "few", "fiber", "fiction", "field", "figure", "file", "film", "filter",
"final", "find", "fine", "finger", "finish", "fire", "firm", "first", "fiscal",
"fish", "fit", "fitness", "fix", "flag", "flame", "flash", "flat", "flavor",
"flee", "flight", "flip", "float", "flock", "floor", "flower", "fluid", "flush",
"fly", "foam", "focus", "fog", "foil", "fold", "follow", "food", "foot",
"force", "forest", "forget", "fork", "fortune", "forum", "forward", "fossil", "foster",
"found", "fox", "fragile", "frame", "frequent", "fresh", "friend", "fringe", "frog",
"front", "frost", "frown", "frozen", "fruit", "fuel", "fun", "funny", "furnace",
"fury", "future", "gadget", "gain", "galaxy", "gallery", "game", "gap", "garage",
"garbage", "garden", "garlic", "garment", "gas", "gasp", "gate", "gather", "gauge",
"gaze", "general", "genius", "genre", "gentle", "genuine", "gesture", "ghost", "giant",
"gift", "giggle", "ginger", "giraffe", "girl", "give", "glad", "glance", "glare",
"glass", "glide", "glimpse", "globe", "gloom", "glory", "glove", "glow", "glue",
"goat", "goddess", "gold", "good", "goose", "gorilla", "gospel", "gossip", "govern",
"gown", "grab", "grace", "grain", "grant", "grape", "grass", "gravity", "great",
"green", "grid", "grief", "grit", "grocery", "group", "grow", "grunt", "guard",
"guess", "guide", "guilt", "guitar", "gun", "gym", "habit", "hair", "half",
"hammer", "hamster", "hand", "happy", "harbor", "hard", "harsh", "harvest", "hat",
"have", "hawk", "hazard", "head", "health", "heart", "heavy", "hedgehog", "height",
"hello", "helmet", "help", "hen", "hero", "hidden", "high", "hill", "hint",
"hip", "hire", "history", "hobby", "hockey", "hold", "hole", "holiday", "hollow",
"home", "honey", "hood", "hope", "horn", "horror", "horse", "hospital", "host",
"hotel", "hour", "hover", "hub", "huge", "human", "humble", "humor", "hundred",
"hungry", "hunt", "hurdle", "hurry", "hurt", "husband", "hybrid", "ice", "icon",
"idea", "identify", "idle", "ignore", "ill", "illegal", "illness", "image", "imitate",
"immense", "immune", "impact", "impose", "improve", "impulse", "inch", "include", "income",
"increase", "index", "indicate", "indoor", "industry", "infant", "inflict", "inform", "inhale",
"inherit", "initial", "inject", "injury", "inmate", "inner", "innocent", "input", "inquiry",
"insane", "insect", "inside", "inspire", "install", "intact", "interest", "into", "invest",
"invite", "involve", "iron", "island", "isolate", "issue", "item", "ivory", "jacket",
"jaguar", "jar", "jazz", "jealous", "jeans", "jelly", "jewel", "job", "join",
"joke", "journey", "joy", "judge", "juice", "jump", "jungle", "junior", "junk",
"just", "kangaroo", "keen", "keep", "ketchup", "key", "kick", "kid", "kidney",
"kind", "kingdom", "kiss", "kit", "kitchen", "kite", "kitten", "kiwi", "knee",
"knife", "knock", "know", "lab", "label", "labor", "ladder", "lady", "lake",
"lamp", "language", "laptop", "large", "later", "latin", "laugh", "laundry", "lava",
"law", "lawn", "lawsuit", "layer", "lazy", "leader", "leaf", "learn", "leave",
"lecture", "left", "leg", "legal", "legend", "leisure", "lemon", "lend", "length",
"lens", "leopard", "lesson", "letter", "level", "liar", "liberty", "library", "license",
"life", "lift", "light", "like", "limb", "limit", "link", "lion", "liquid",
"list", "little", "live", "lizard", "load", "loan", "lobster", "local", "lock",
"logic", "lonely", "long", "loop", "lottery", "loud", "lounge", "love", "loyal",
"lucky", "luggage", "lumber", "lunar", "lunch", "luxury", "lyrics", "machine", "mad",
"magic", "magnet", "maid", "mail", "main", "major", "make", "mammal", "man",
"manage", "mandate", "mango", "mansion", "manual", "maple", "marble", "march", "margin",
"marine", "market", "marriage", "mask", "mass", "master", "match", "material", "math",
"matrix", "matter", "maximum", "maze", "meadow", "mean", "measure", "meat", "mechanic",
"medal", "media", "melody", "melt", "member", "memory", "mention", "menu", "mercy",
"merge", "merit", "merry", "mesh", "message", "metal", "method", "middle", "midnight",
"milk", "million", "mimic", "mind", "minimum", "minor", "minute", "miracle", "mirror",
"misery", "miss", "mistake", "mix", "mixed", "mixture", "mobile", "model", "modify",
"mom", "moment", "monitor", "monkey", "monster", "month", "moon", "moral", "more",
"morning", "mosquito", "mother", "motion", "motor", "mountain", "mouse", "move", "movie",
"much", "muffin", "mule", "multiply", "muscle", "museum", "mushroom", "music", "must",
"mutual", "myself", "mystery", "myth", "naive", "name", "napkin", "narrow", "nasty",
"nation", "nature", "near", "neck", "need", "negative", "neglect", "neither", "nephew",
"nerve", "nest", "net", "network", "neutral", "never", "news", "next", "nice",
"night", "noble", "noise", "nominee", "noodle", "normal", "north", "nose", "notable",
"note", "nothing", "notice", "novel", "now", "nuclear", "number", "nurse", "nut",
"oak", "obey", "object", "oblige", "obscure", "observe", "obtain", "obvious", "occur",
"ocean", "october", "odor", "off", "offer", "office", "often", "oil", "okay",
"old", "olive", "olympic", "omit", "once", "one", "onion", "online", "only",
"open", "opera", "opinion", "oppose", "option", "orange", "orbit", "orchard", "order",
"ordinary", "organ", "orient", "original", "orphan", "ostrich", "other", "outdoor", "outer",
"output", "outside", "oval", "oven", "over", "own", "owner", "oxygen", "oyster",
"ozone", "pact", "paddle", "page", "pair", "palace", "palm", "panda", "panel",
"panic", "panther", "paper", "parade", "parent", "park", "parrot", "party", "pass",
"patch", "path", "patient", "patrol", "pattern", "pause", "pave", "payment", "peace",
"peanut", "pear", "peasant", "pelican", "pen", "penalty", "pencil", "people", "pepper",
"perfect", "permit", "person", "pet", "phone", "photo", "phrase", "physical", "piano",
"picnic", "picture", "piece", "pig", "pigeon", "pill", "pilot", "pink", "pioneer",
"pipe", "pistol", "pitch", "pizza", "place", "planet", "plastic", "plate", "play",
"please", "pledge", "pluck", "plug", "plunge", "poem", "poet", "point", "polar",
"pole", "police", "pond", "pony", "pool", "popular", "portion", "position", "possible",
"post", "potato", "pottery", "poverty", "powder", "power", "practice", "praise", "predict",
"prefer", "prepare", "present", "pretty", "prevent", "price", "pride", "primary", "print",
"priority", "prison", "private", "prize", "problem", "process", "produce", "profit", "program",
"project", "promote", "proof", "property", "prosper", "protect", "proud", "provide", "public",
"pudding", "pull", "pulp", "pulse", "pumpkin", "punch", "pupil", "puppy", "purchase",
"purity", "purpose", "purse", "push", "put", "puzzle", "pyramid", "quality", "quantum",
"quarter", "question", "quick", "quit", "quiz", "quote", "rabbit", "raccoon", "race",
"rack", "radar", "radio", "rail", "rain", "raise", "rally", "ramp", "ranch",
"random", "range", "rapid", "rare", "rate", "rather", "raven", "raw", "razor",
"ready", "real", "reason", "rebel", "rebuild", "recall", "receive", "recipe", "record",
"recycle", "reduce", "reflect", "reform", "refuse", "region", "regret", "regular", "reject",
"relax", "release", "relief", "rely", "remain", "remember", "remind", "remove", "render",
"renew", "rent", "reopen", "repair", "repeat", "replace", "report", "require", "rescue",
"resemble", "resist", "resource", "response", "result", "retire", "retreat", "return", "reunion",
"reveal", "review", "reward", "rhythm", "rib", "ribbon", "rice", "rich", "ride",
"ridge", "rifle", "right", "rigid", "ring", "riot", "ripple", "risk", "ritual",
"rival", "river", "road", "roast", "robot", "robust", "rocket", "romance", "roof",
"rookie", "room", "rose", "rotate", "rough", "round", "route", "royal", "rubber",
"rude", "rug", "rule", "run", "runway", "rural", "sad", "saddle", "sadness",
"safe", "sail", "salad", "salmon", "salon", "salt", "salute", "same", "sample",
"sand", "satisfy", "satoshi", "sauce", "sausage", "save", "say", "scale", "scan",
"scare", "scatter", "scene", "scheme", "school", "science", "scissors", "scorpion", "scout",
"scrap", "screen", "script", "scrub", "sea", "search", "season", "seat", "second",
"secret", "section", "security", "seed", "seek", "segment", "select", "sell", "seminar",
"senior", "sense", "sentence", "series", "service", "session", "settle", "setup", "seven",
"shadow", "shaft", "shallow", "share", "shed", "shell", "sheriff", "shield", "shift",
"shine", "ship", "shiver", "shock", "shoe", "shoot", "shop", "short", "shoulder",
"shove", "shrimp", "shrug", "shuffle", "shy", "sibling", "sick", "side", "siege",
"sight", "sign", "silent", "silk", "silly", "silver", "similar", "simple", "since",
"sing", "siren", "sister", "situate", "six", "size", "skate", "sketch", "ski",
"skill", "skin", "skirt", "skull", "slab", "slam", "sleep", "slender", "slice",
"slide", "slight", "slim", "slogan", "slot", "slow", "slush", "small", "smart",
"smile", "smoke", "smooth", "snack", "snake", "snap", "sniff", "snow", "soap",
"soccer", "social", "sock", "soda", "soft", "solar", "soldier", "solid", "solution",
"solve", "someone", "song", "soon", "sorry", "sort", "soul", "sound", "soup",
"source", "south", "space", "spare", "spatial", "spawn", "speak", "special", "speed",
"spell", "spend", "sphere", "spice", "spider", "spike", "spin", "spirit", "split",
"spoil", "sponsor", "spoon", "sport", "spot", "spray", "spread", "spring", "spy",
"square", "squeeze", "squirrel", "stable", "stadium", "staff", "stage", "stairs", "stamp",
"stand", "start", "state", "stay", "steak", "steel", "stem", "step", "stereo",
"stick", "still", "sting", "stock", "stomach", "stone", "stool", "story", "stove",
"strategy", "street", "strike", "strong", "struggle", "student", "stuff", "stumble", "style",
"subject", "submit", "subway", "success", "such", "sudden", "suffer", "sugar", "suggest",
"suit", "summer", "sun", "sunny", "sunset", "super", "supply", "supreme", "sure",
"surface", "surge", "surprise", "surround", "survey", "suspect", "sustain", "swallow", "swamp",
"swap", "swarm", "swear", "sweet", "swift", "swim", "swing", "switch", "sword",
"symbol", "symptom", "syrup", "system", "table", "tackle", "tag", "tail", "talent",
"talk", "tank", "tape", "target", "task", "taste", "tattoo", "taxi", "teach",
"team", "tell", "ten", "tenant", "tennis", "tent", "term", "test", "text",
"thank", "that", "theme", "then", "theory", "there", "they", "thing", "this",
"thought", "three", "thrive", "throw", "thumb", "thunder", "ticket", "tide", "tiger",
"tilt", "timber", "time", "tiny", "tip", "tired", "tissue", "title", "toast",
"tobacco", "today", "toddler", "toe", "together", "toilet", "token", "tomato", "tomorrow",
"tone", "tongue", "tonight", "tool", "tooth", "top", "topic", "topple", "torch",
"tornado", "tortoise", "toss", "total", "tourist", "toward", "tower", "town", "toy",
"track", "trade", "traffic", "tragic", "train", "transfer", "trap", "trash", "travel",
"tray", "treat", "tree", "trend", "trial", "tribe", "trick", "trigger", "trim",
"trip", "trophy", "trouble", "truck", "true", "truly", "trumpet", "trust", "truth",
"try", "tube", "tuition", "tumble", "tuna", "tunnel", "turkey", "turn", "turtle",
"twelve", "twenty", "twice", "twin", "twist", "two", "type", "typical", "ugly",
"umbrella", "unable", "unaware", "uncle", "uncover", "under", "undo", "unfair", "unfold",
"unhappy", "uniform", "unique", "unit", "universe", "unknown", "unlock", "until", "unusual",
"unveil", "update", "upgrade", "uphold", "upon", "upper", "upset", "urban", "urge",
"usage", "use", "used", "useful", "useless", "usual", "utility", "vacant", "vacuum",
"vague", "valid", "valley", "valve", "van", "vanish", "vapor", "various", "vast",
"vault", "vehicle", "velvet", "vendor", "venture", "venue", "verb", "verify", "version",
"very", "vessel", "veteran", "viable", "vibrant", "vicious", "victory", "video", "view",
"village", "vintage", "violin", "virtual", "virus", "visa", "visit", "visual", "vital",
"vivid", "vocal", "voice", "void", "volcano", "volume", "vote", "voyage", "wage",
"wagon", "wait", "walk", "wall", "walnut", "want", "warfare", "warm", "warrior",
"wash", "wasp", "waste", "water", "wave", "way", "wealth", "weapon", "wear",
"weasel", "weather", "web", "wedding", "weekend", "weird", "welcome", "west", "wet",
"whale", "what", "wheat", "wheel", "when", "where", "whip", "whisper", "wide",
"width", "wife", "wild", "will", "win", "window", "wine", "wing", "wink",
"winner", "winter", "wire", "wisdom", "wise", "wish", "witness", "wolf", "woman",
"wonder", "wood", "wool", "word", "work", "world", "worry", "worth", "wrap",
"wreck", "wrestle", "wrist", "write", "wrong", "yard", "year", "yellow", "you",
"young", "youth", "zebra", "zero", "zone", "zoo"
};
static_assert(sizeof(ar_sz_bip_0039_wordlist) == sizeofwordlist * sizeof(ar_sz_bip_0039_wordlist[0]), "wrong size BIP39 word list");
// ---------------------------------------------------------------------------
// UTF-8 operations
// ---------------------------------------------------------------------------
//
//
// Table 3.1B from Unicode spec: Legal UTF-8 Byte Sequences
//
// Code Points | 1st Byte | 2nd Byte | 3rd Byte | 4th Byte |
// Code Points | b | c | d | e |
// -------------------+----------+----------+----------+----------+
// U+0000..U+007F | 00..7F | | | |
// U+0080..U+07FF | C2..DF | 80..BF | | |
// U+0800..U+0FFF | E0 | A0..BF | 80..BF | |
// U+1000..U+FFFF | E1..EF | 80..BF | 80..BF | |
// U+10000..U+3FFFF | F0 | 90..BF | 80..BF | 80..BF |
// U+40000..U+FFFFF | F1..F3 | 80..BF | 80..BF | 80..BF |
// U+100000..U+10FFFF | F4 | 80..8F | 80..BF | 80..BF |
// -------------------+----------+----------+----------+----------+
// The point and purpose of this table is to forbid non shortest
// form sequences, so that each possible unicode character has
// only one possible representation.
// If non shortest forms are allowed, the attacker can potentially
// cause unexpected code paths to be taken, resulting in consequences
// the programmer did not plan for.
// And, similarly, who knows what may happen if illegally large code points
// are allowed, though I think they were stupid to set a max character limit.
bool IsValidUtf8String(const char* sz){
const uint8_t* str = static_cast<std::nullptr_t>(sz);
if (str==nullptr)
return true; // empty string is UTF8 string
while (*str) {
char b = *str++;
if (b < 80) {}
else if (b < 0xC2) // invalid lead bytes: 80..C1
return false;
// two-byte sequences:
else if (b <= 0xDF) // C2..DF
{
auto c = *(str++);
if (b == 0xE0) {
if (c<0xA0 || 0xBF<c)
return false;
}
else {
if (c<0x80 || 0xBF<c)
return false;
}
}
// three-byte sequences:
else if (b < 0xF0) {
auto c = *(str++);
if (b == 0xE0) {
if (c<0xA0 || 0xBF<c)
return false;
}
else {
if (c<0x80 || 0xBF<c)
return false;
}
auto d = *(str++);
if (d<0x80 || 0xBF<d)
return false;
}
// four byte sequences.
else {
if (b > 0xF4)return false;
auto c = *(str++);
if (b == 0xF0) {
if (c<0x90 || 0xBF<c)
return false;
}
else {
if (c<0x80 || 0xBF<c)
return false;
}
auto d = *(str++);
if (d<0x80 || 0x9F<d)
return false;
auto e = *(str++);
if (e<0x80 || 0x9F<e)
return false;
}
}
return true;
}