Module nimfuzz

Simple and compact Nim fuzzing library based on the great fauxfactory. The primary purpose of the library is to generate random strings to test the security of common utilities to help defend your system.

Author: Jonathan Edwards
Version: 1.2.0
Copyright: 2015 Jonathan Edwards. Apache License 2.0

Lets

UnicodeLetters = ch
Unicode characters from 0 to 0x10ffff

Consts

Schemes = ["ftp", "sftp", "http", "https"]
Valid URL Schemes
ExSchemes = ["aaa", "aaas", "about", "acap", "acct", "cap", "cid", "coap", 
             "coaps", "crid", "data", "dav", "dict", "dns", "example", "file", 
             "ftp", "sftp", "geo", "go", "gopher", "h323", "http", "https", 
             "iax", "icap", "im", "imap", "info", "ipp", "ipps", "iris", 
             "iris.beep", "iris.xpc", "iris.xpcs", "iris.lws", "jabber", "ldap", 
             "mailto", "mid", "msrp", "msrps", "mtqp", "mupdate", "news", "nfs", 
             "ni", "nih", "nntp", "opaquelocktoken", "pkcs11", "pop", "pres", 
             "reload", "rtsp", "service", "session", "shttp", "sieve", "sip", 
             "sips", "sms", "snmp", "soap.beep", "soap.beeps", "stun", "stuns", 
             "tag", "tel", "telnet", "tftp", "thismessage", "tn3270", "tip", 
             "turn", "turns", "tv", "urn", "vemmi", "ws", "wss", "xcon", 
             "xcon-userid", "xmlrpc.beep", "xmlrpc.beeps", "xmpp", "z39.50r", 
             "z39.50s", "app", "doi", "javascript", "jdbc", "odbc", "stratum", 
             "vnc", "web"]
Extended but permanent valid URL schemes
Subdomains = ["example", "test"]
Valid subdomains for URL and email
Tlds = ["biz", "com", "edu", "gov", "info", "org", "net", "mil"]
Valid top-level domains for URL and email
InternationalTlds = ["\xD0\xB1\xD0\xB5\xD0\xBB", "\xD2\x9B\xD0\xB0\xD0\xB7", 
                     "\xD0\xBC\xD0\xBE\xD0\xBD", "\xD0\xBC\xD0\xBA\xD0\xB4", 
                     "\xD1\x80\xD1\x84", "\xD1\x81\xD1\x80\xD0\xB1", 
                     "\xD1\x83\xD0\xBA\xD1\x80", "\xD8\xA7\xD9\x84\xD8\xAC\xD8\xB2\xD8\xA7\xD8\xA6\xD8\xB1", 
                     "\xD9\x85\xD8\xB5\xD8\xB1", 
                     "\xD8\xA8\xDA\xBE\xD8\xA7\xD8\xB1\xD8\xAA", 
                     "\xD8\xA7\xDB\x8C\xD8\xB1\xD8\xA7\xD9\x86", 
                     "\xD8\xA7\xD9\x84\xD8\xA7\xD8\xB1\xD8\xAF\xD9\x86", 
                     "\xD9\x81\xD9\x84\xD8\xB3\xD8\xB7\xD9\x8A\xD9\x86", "\xD9\xBE\xD8\xA7\xDA\xA9\xD8\xB3\xD8\xAA\xD8\xA7\xD9\x86", 
                     "\xD9\x82\xD8\xB7\xD8\xB1", "\xD8\xA7\xD9\x84\xD8\xB3\xD8\xB9\xD9\x88\xD8\xAF\xD9\x8A\xD8\xA9", 
                     "\xD8\xB3\xD9\x88\xD8\xB1\xD9\x8A\xD8\xA7", 
                     "\xD8\xAA\xD9\x88\xD9\x86\xD8\xB3", 
                     "\xD8\xA7\xD9\x85\xD8\xA7\xD8\xB1\xD8\xA7\xD8\xAA", 
                     "\xD8\xB9\xD9\x85\xD8\xA7\xD9\x86", 
                     "\xD9\x85\xD9\x84\xD9\x8A\xD8\xB3\xD9\x8A\xD8\xA7", 
                     "\xD8\xA7\xD9\x84\xD9\x85\xD8\xBA\xD8\xB1\xD8\xA8", 
                     "\xD8\xB3\xD9\x88\xD8\xAF\xD8\xA7\xD9\x86", 
                     "\xD8\xA7\xD9\x84\xD9\x8A\xD9\x85\xD9\x86", "\xE0\xA6\xAC\xE0\xA6\xBE\xE0\xA6\x82\xE0\xA6\xB2\xE0\xA6\xBE", 
                     "\xE0\xA6\xAD\xE0\xA6\xBE\xE0\xA7\xB0\xE0\xA6\xA4", 
                     "\xE0\xA6\xAD\xE0\xA6\xBE\xE0\xA6\xB0\xE0\xA6\xA4", 
                     "\xE0\xA4\xAD\xE0\xA4\xBE\xE0\xA4\xB0\xE0\xA4\xA4", "\xE0\xB0\xAD\xE0\xB0\xBE\xE0\xB0\xB0\xE0\xB0\xA4\xE0\xB1\x8D", 
                     "\xE0\xAA\xAD\xE0\xAA\xBE\xE0\xAA\xB0\xE0\xAA\xA4", 
                     "\xE0\xA8\xAD\xE0\xA8\xBE\xE0\xA8\xB0\xE0\xA8\xA4", 
                     "\xE0\xAC\xAD\xE0\xAC\xBE\xE0\xAC\xB0\xE0\xAC\xA4", "\xE0\xAE\x87\xE0\xAE\xA8\xE0\xAF\x8D\xE0\xAE\xA4\xE0\xAE\xBF\xE0\xAE\xAF\xE0\xAE\xBE", 
                     "\xE0\xB6\xBD\xE0\xB6\x82\xE0\xB6\x9A\xE0\xB7\x8F", "\xE0\xAE\x87\xE0\xAE\xB2\xE0\xAE\x99\xE0\xAF\x8D\xE0\xAE\x95\xE0\xAF\x88", 
                     "\xE0\xB9\x84\xE0\xB8\x97\xE0\xB8\xA2", "\xE0\xAE\x9A\xE0\xAE\xBF\xE0\xAE\x99\xE0\xAF\x8D\xE0\xAE\x95\xE0\xAE\xAA\xE0\xAF\x8D\xE0\xAE\xAA\xE0\xAF\x82\xE0\xAE\xB0\xE0\xAF\x8D", 
                     "\xE4\xB8\xAD\xE5\x9B\xBD", "\xE4\xB8\xAD\xE5\x9C\x8B", 
                     "\xE9\xA6\x99\xE6\xB8\xAF", "\xE5\x8F\xB0\xE7\x81\xA3", 
                     "\xE5\x8F\xB0\xE6\xB9\xBE", 
                     "\xE6\x96\xB0\xE5\x8A\xA0\xE5\x9D\xA1", 
                     "\xE6\xBE\xB3\xE9\x96\x80", "\xE6\xBE\xB3\xE9\x97\xA8", 
                     "\xE1\x83\x92\xE1\x83\x94", "\xED\x95\x9C\xEA\xB5\xAD", 
                     "\xD5\xB0\xD5\xA1\xD5\xB5"]
LoremIpsum = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
Lorem Ipsum text
ValidNetmasks = ["0.0.0.0", "128.0.0.0", "192.0.0.0", "224.0.0.0", "240.0.0.0", 
                 "248.0.0.0", "252.0.0.0", "254.0.0.0", "255.0.0.0", 
                 "255.128.0.0", "255.192.0.0", "255.224.0.0", "255.240.0.0", 
                 "255.248.0.0", "255.252.0.0", "255.254.0.0", "255.255.0.0", 
                 "255.255.128.0", "255.255.192.0", "255.255.224.0", 
                 "255.255.240.0", "255.255.248.0", "255.255.252.0", 
                 "255.255.254.0", "255.255.255.0", "255.255.255.128", 
                 "255.255.255.192", "255.255.255.224", "255.255.255.240", 
                 "255.255.255.248", "255.255.255.252", "255.255.255.254", 
                 "255.255.255.255"]
Valid Netmasks
HtmlTags = ["a", "abbr", "acronym", "address", "applet", "area", "b", "base", 
            "basefont", "bdo", "big", "blink", "blockquote", "body", "br", 
            "button", "caption", "center", "cite", "code", "col", "colgroup", 
            "dd", "del", "dfn", "dir", "div", "dl", "dt", "em", "fieldset", 
            "font", "form", "frame", "frameset", "h1", "h2", "h3", "h4", "h5", 
            "h6", "head", "hr", "html", "i", "iframe", "img", "input", "ins", 
            "isindex", "kbd", "label", "legend", "li", "link", "map", "menu", 
            "meta", "noframes", "noscript", "object", "ol", "optgroup", 
            "option", "p", "param", "pre", "q", "s", "samp", "script", "select", 
            "small", "span", "strike", "strong", "style", "sub", "sup", "table", 
            "tbody", "td", "textarea", "tfoot", "th", "thead", "title", "tr", 
            "tt", "u", "ul", "var"]
Valid HTML tags
AsciiLower = "abcdefghijklmnopqrstuvwxyz"
Lowercase alphas
AsciiUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
Uppercase alphas
AsciiLetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
All alphas
Digits = "0123456789"
All digits
HexDigitsLower = "abcdef0123456789"
Lowercase hex digits
HexDigits = "ABCDEFabcdef0123456789"
All hex digits
OctDigits = "01234567"
All octal digits

Procs

proc genAlpha(length = 10): string {.noSideEffect, inline, raises: [], tags: [].}
Generate a length-long alphabetic string;
echo genAlpha() # PhQGHuMEAy
proc genAlphanumeric(length = 10; upper = true): string {.noSideEffect, 
    raises: [], tags: [].}
Generate a length-long alphanumeric string; All letters lowercase unless upper is true
echo genAlphanumeric() # f98er24s8u
proc genChoice[T](choices: openArray[T]): T {.noSideEffect.}
Generate a random item from choices
proc genBool(): bool {.noSideEffect, inline, raises: [], tags: [].}
Generates either true or false
proc genCjk(length = 10): string {.noSideEffect, inline, raises: [], tags: [].}
Generate a random string made up of CJK characters
echo genCjk(8) # 鍖磎仓鰀襓被澙齪
proc genCyrillic(length = 10): string {.noSideEffect, inline, raises: [], 
                                        tags: [].}
Generate a random string made up of Cyrillic characters
echo genCyrillic(5) # "ЋӅДӈҧ"
proc genEmail(name, domain, tld: string = ""): string {.noSideEffect, 
    raises: [], tags: [].}
Generate a random email address
echo genEmail() # lenPFfhV@example.gov
echo genEmail(domain = genAlpha(6)) # sRISqUvc@QazEsO.gov
proc genIpsum(words = 0; paragraphs: int): string {.noSideEffect, raises: [], 
    tags: [].}
Generate a custom version of the classic nonsense Lorem Ipsum text. words is the number of words per paragraph; paragraphs is the number of paragraphs overall
echo genIpsum(words = 5, paragraphs = 3)
# Lorem ipsum dolor sit amet
# Consectetur adipisicing elit, sed do
# Eiusmod tempor incididunt ut labore
proc genLatin1(length = 10): string {.noSideEffect, inline, raises: [], tags: [].}
Generate a random string made up of UTF-8 characters
echo genLatin1(20) # ãÄñäÒ÷ûÿßôüàêÖÈéáòûÎ
proc genIpaddr(ip3 = false; ipv6 = false; prefix: seq[string] = nil): string {.
    noSideEffect, raises: [ValueError], tags: [].}
Generate a random IP address
echo genIpaddr() # 65.62.237.168
echo genIpaddr(ipv6 = true) # 076d:5c0d:6ced:2649:b44b:af26:7b06:8db3
echo genIpaddr(prefix = ["this"]) # this.141.204.179
# Making sure it makes sense is up to you ;-)
proc genIpaddr(ip3 = false; ipv6 = false; prefix: openArray[int]): string {.
    noSideEffect, raises: [ValueError], tags: [].}
Generate a random IP address with a given prefix
echo genIpaddr(prefix = [10]) # 10.163.127.20
echo genIpaddr(prefix = [10,3]) # 10.3.251.78
echo genIpaddr(prefix = [10,3], ipv6 = true)
# 10:3:605d:b501:6cb5:4e1b:736c:f1c8
proc genMac(delimiter = ":"): string {.noSideEffect, inline, raises: [], 
                                       tags: [].}
Generate a random MAC address with either ':' (default) or '-' as the delimiter
echo genMac() # 34:ed:50:7b:11:d1
proc genNetmask(minCidr = 1; maxCidr = 31): string {.noSideEffect, raises: [], 
    tags: [].}
Generate a random valid netmask
echo genNetmask() # 255.224.0.0
proc genNumericString(length = 10): string {.noSideEffect, raises: [], tags: [].}
Generate a random string made up of numbers
echo genNumericString() # 1740948824
proc genTime(): TimeInfo {.noSideEffect, raises: [], tags: [].}
Generate a random time and returns a TimeInfo object
echo genTime() # Mon Sep 22 03:43:47 2701
proc genUrl(extended = false; internationalized = false): string {.noSideEffect, 
    raises: [], tags: [].}
Generate a random URL. If extended is true, the URL scheme is generated from ExSchemes instead of Schemes. If internationalized is true, generates URL with interationalized TLD.
echo genUrl(extended = true) # msrps://test.info
echo genUrl(true, true) # imap://example.新加坡
proc genUtf8(length = 10): string {.raises: [], tags: [].}

Generate a random string made up of UTF-8 letters characters

CJK seems to dominate the ranges, which makes sense

echo genUtf8() # p觖婱딷貔缟溉쁡뜅굃
proc genHtml(length = 10): string {.noSideEffect, raises: [ValueError], tags: [].}
Generate a random string made up of html characters
echo genHtml() # <head>hQGHuMEAyL</head>
proc genUuid(valid = true): string {.noSideEffect, raises: [], tags: [].}

Generate a random UUID

valid makes sure some of it makes sense. It doesn't actually make sure it lines up with valid UUID versions

echo genUuid() # 3d8eb608-ca3b-3876-a118-b535d0561683
proc asBytes(s: string): seq[byte] {.noSideEffect, raises: [], tags: [].}
Output some string as a byte sequence This can be combined with most of the fuzzing functions
echo genUtf8(2).asBytes
# @[229, 137, 145, 229, 191, 131]