LLVMFuzzerTestOneInput:
    5|    428|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    6|       |
    7|    428|    std::string modifiableInput((char *) data, size);
    8|       |
    9|    428|    uWS::getDecodedQueryValue("", modifiableInput);
   10|    428|    uWS::getDecodedQueryValue("hello", modifiableInput);
   11|       |
   12|    428|    return 0;
   13|    428|}

QueryParser.cpp:_ZN3uWSL20getDecodedQueryValueENSt3__117basic_string_viewIcNS0_11char_traitsIcEEEES4_:
   28|    856|    static inline std::string_view getDecodedQueryValue(std::string_view key, std::string_view rawQuery) {
   29|       |
   30|       |        /* Can't have a value without a key */
   31|    856|        if (!key.length()) {
  ------------------
  |  Branch (31:13): [True: 428, False: 428]
  ------------------
   32|    428|            return {};
   33|    428|        }
   34|       |
   35|       |        /* Start with the whole querystring including initial '?' */
   36|    428|        std::string_view queryString = rawQuery;
   37|       |
   38|       |        /* List of key, value could be cached for repeated fetches similar to how headers are, todo! */
   39|  2.34k|        while (queryString.length()) {
  ------------------
  |  Branch (39:16): [True: 2.13k, False: 204]
  ------------------
   40|       |            /* Find boundaries of this statement */
   41|  2.13k|            std::string_view statement = queryString.substr(1, queryString.find('&', 1) - 1);
   42|       |
   43|       |            /* Only bother if first char of key match (early exit) */
   44|  2.13k|            if (statement.length() && statement[0] == key[0]) {
  ------------------
  |  Branch (44:17): [True: 1.60k, False: 532]
  |  Branch (44:39): [True: 906, False: 699]
  ------------------
   45|       |                /* Equal sign must be present and not in the end of statement */
   46|    906|                auto equality = statement.find('=');
   47|    906|                if (equality != std::string_view::npos) {
  ------------------
  |  Branch (47:21): [True: 900, False: 6]
  ------------------
   48|       |
   49|    900|                    std::string_view statementKey = statement.substr(0, equality);
   50|    900|                    std::string_view statementValue = statement.substr(equality + 1);
   51|       |
   52|       |                    /* String comparison */
   53|    900|                    if (key == statementKey) {
  ------------------
  |  Branch (53:25): [True: 218, False: 682]
  ------------------
   54|       |
   55|       |                        /* Decode value inplace, put null at end if before length of original */
   56|    218|                        char *in = (char *) statementValue.data();
   57|       |
   58|       |                        /* Write offset */
   59|    218|                        unsigned int out = 0;
   60|       |
   61|       |                        /* Walk over all chars until end or null char, decoding in place */
   62|  3.17M|                        for (unsigned int i = 0; i < statementValue.length() && in[i]; i++) {
  ------------------
  |  Branch (62:50): [True: 3.17M, False: 82]
  |  Branch (62:81): [True: 3.17M, False: 100]
  ------------------
   63|       |                                /* Only bother with '%' */
   64|  3.17M|                                if (in[i] == '%') {
  ------------------
  |  Branch (64:37): [True: 118k, False: 3.05M]
  ------------------
   65|       |                                    /* Do we have enough data for two bytes hex? */
   66|   118k|                                    if (i + 2 >= statementValue.length()) {
  ------------------
  |  Branch (66:41): [True: 36, False: 118k]
  ------------------
   67|     36|                                        return {};
   68|     36|                                    }
   69|       |
   70|       |                                    /* Two bytes hex */
   71|   118k|                                    int hex1 = in[i + 1] - '0';
   72|   118k|                                    if (hex1 > 9) {
  ------------------
  |  Branch (72:41): [True: 103k, False: 15.2k]
  ------------------
   73|   103k|                                        hex1 &= 223;
   74|   103k|                                        hex1 -= 7;
   75|   103k|                                    }
   76|       |
   77|   118k|                                    int hex2 = in[i + 2] - '0';
   78|   118k|                                    if (hex2 > 9) {
  ------------------
  |  Branch (78:41): [True: 81.6k, False: 36.6k]
  ------------------
   79|  81.6k|                                        hex2 &= 223;
   80|  81.6k|                                        hex2 -= 7;
   81|  81.6k|                                    }
   82|       |
   83|   118k|                                    *((unsigned char *) &in[out]) = (unsigned char) (hex1 * 16 + hex2);
   84|   118k|                                    i += 2;
   85|  3.05M|                                } else {
   86|       |                                    /* Is this even a rule? */
   87|  3.05M|                                    if (in[i] == '+') {
  ------------------
  |  Branch (87:41): [True: 2.14k, False: 3.05M]
  ------------------
   88|  2.14k|                                        in[out] = ' ';
   89|  3.05M|                                    } else {
   90|  3.05M|                                        in[out] = in[i];
   91|  3.05M|                                    }
   92|  3.05M|                                }
   93|       |
   94|       |                                /* We always only write one char */
   95|  3.17M|                                out++;
   96|  3.17M|                        }
   97|       |
   98|       |                        /* If decoded string is shorter than original, put null char to stop next read */
   99|    182|                        if (out < statementValue.length()) {
  ------------------
  |  Branch (99:29): [True: 146, False: 36]
  ------------------
  100|    146|                            in[out] = 0;
  101|    146|                        }
  102|       |
  103|    182|                        return statementValue.substr(0, out);
  104|    218|                    }
  105|    900|                } else {
  106|       |                    /* This querystring is invalid, cannot parse it */
  107|      6|                    return {nullptr, 0};
  108|      6|                }
  109|    906|            }
  110|       |
  111|  1.91k|            queryString.remove_prefix(statement.length() + 1);
  112|  1.91k|        }
  113|       |
  114|       |        /* Nothing found is given as nullptr, while empty string is given as some pointer to the given buffer */
  115|    204|        return {nullptr, 0};
  116|    428|    }

