static PyObject * Codec_decode(Codec *self, PyObject *args) { const char* in = NULL; int inlen = 0; if (!PyArg_ParseTuple(args, "s#:decode", &in, &inlen)) return NULL; char* out = NULL; PyObject *result = NULL; Py_ssize_t size; /* First pass: calculate size of decoded string. Create a new string object of exactly that size. */ size = percent_decode(in, inlen, NULL); if (!(result = PyString_FromStringAndSize(NULL,size))) return NULL; /* Second pass: actually decode this time. */ out = PyString_AsString(result); size = percent_decode(in, inlen, out); return result; }
static int on_frame_recv_callback(nghttp2_session *session, const nghttp2_frame *frame, void *user_data) { http2_session_data *session_data = (http2_session_data*)user_data; http2_stream_data *stream_data; size_t i; const char PATH[] = ":path"; switch(frame->hd.type) { case NGHTTP2_HEADERS: if(frame->headers.cat != NGHTTP2_HCAT_REQUEST) { break; } stream_data = create_http2_stream_data(session_data, frame->hd.stream_id); nghttp2_session_set_stream_user_data(session, frame->hd.stream_id, stream_data); for(i = 0; i < frame->headers.nvlen; ++i) { nghttp2_nv *nv = &frame->headers.nva[i]; if(nv->namelen == sizeof(PATH) - 1 && memcmp(PATH, nv->name, nv->namelen) == 0) { size_t j; for(j = 0; j < nv->valuelen && nv->value[j] != '?'; ++j); stream_data->request_path = percent_decode(nv->value, j); break; } } break; default: break; } return 0; }
/** Разбор URL-строки */ void UrlParser::parse() { port = 80; mainParse(url_); // Ищем первый вопросительный знак std::string::size_type pos = url_.find_first_of('?'); if (pos == std::string::npos) pos = -1; while (pos < url_.size() || pos == (std::string::size_type)-1) { // Выделяем название параметра std::string::size_type end = url_.find_first_of('=', ++pos); if (end == std::string::npos) return; std::string param_name = url_.substr(pos, end - pos); pos = end; // Выделяем значение параметра end = url_.find_first_of('&', ++pos); if (end == std::string::npos) end = url_.size(); std::string param_value = url_.substr(pos, end - pos); pos = end; params_[param_name] = percent_decode(param_value); } }
/* nghttp2_on_header_callback: Called when nghttp2 library emits single header name/value pair. */ static int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, size_t namelen, const uint8_t *value, size_t valuelen, uint8_t flags, void *user_data) { http2_stream_data *stream_data; const char PATH[] = ":path"; (void)flags; (void)user_data; switch (frame->hd.type) { case NGHTTP2_HEADERS: if (frame->headers.cat != NGHTTP2_HCAT_REQUEST) { break; } stream_data = nghttp2_session_get_stream_user_data(session, frame->hd.stream_id); if (!stream_data || stream_data->request_path) { break; } if (namelen == sizeof(PATH) - 1 && memcmp(PATH, name, namelen) == 0) { size_t j; for (j = 0; j < valuelen && value[j] != '?'; ++j) ; stream_data->request_path = percent_decode(value, j); } break; } return 0; }
void request_parser::parse_params(request& req) { std::string request_uri = percent_decode(req.uri); boost::split(req.rest_params, request_uri, boost::is_any_of("/")); req.rest_params.erase(req.rest_params.begin()); if (req.params.size() == 0) { return; } for (std::size_t i = 0; i < req.params.size(); ++i) { req.params[i].name = percent_decode(req.params[i].name); req.params[i].value = percent_decode(req.params[i].value); } }
static int uri_parse_authority(const char *authority, struct uri *uri) { const char *portsep; const char *host_start, *host_end; char *tail; /* We do not support "user:pass@" userinfo. The proxy has no use for it. */ if (strchr(authority, '@') != NULL) return -1; /* Find the beginning and end of the host. */ host_start = authority; if (*host_start == '[') { /* IPv6 address in brackets. */ host_start++; host_end = strchr(host_start, ']'); if (host_end == NULL) return -1; portsep = host_end + 1; if (!(*portsep == ':' || *portsep == '\0')) return -1; } else { portsep = strrchr(authority, ':'); if (portsep == NULL) portsep = strchr(authority, '\0'); host_end = portsep; } /* Get the port number. */ if (*portsep == ':' && *(portsep + 1) != '\0') { long n; errno = 0; n = parse_long(portsep + 1, &tail); if (errno || *tail || (tail == (portsep + 1)) || !IN_RANGE(n, 1, 65535)) return -1; uri->port = n; } else { uri->port = -1; } /* Get the host. */ uri->host = mkstr(host_start, host_end); if (percent_decode(uri->host) < 0) { free(uri->host); uri->host = NULL; return -1; } return 1; }
bool parse_host(std::string const& input, url_t* url, bool* errors) { if (input[0] == '[') { if (input.back() != ']') return false; return ipv6_parse_host(input.substr(1, input.size() - 2), url, errors); } std::string domain = percent_decode(input.c_str()); for (char chr : domain) { switch (chr) { case 0x00: case 0x09: case 0x0A: case 0x0D: case 0x20: case '#': case '%': case '/': case ':': case '?': case '@': case '[': case '\\': case ']': return false; } } return ipv4_parse_host(domain, url, errors); }
multipart_header request_parser::parse_multipart_header(request& req, const std::string& data) { std::string disposition; disposition = extract_between(data, "Content-Disposition: ", ";"); std::string name; name = extract_between(data, "name=\"", "\""); std::string filename; filename = extract_between(data, "filename=\"", "\""); std::string c_type; c_type = extract_between(data, "Content-Type: ", "\r\n\r\n"); filename = percent_decode(filename); return multipart_header(disposition, name, filename, c_type); }
isc_result_t pk11_parse_uri(pk11_object_t *obj, const char *label, isc_mem_t *mctx, pk11_optype_t optype) { CK_ATTRIBUTE *attr; pk11_token_t *token = NULL; char *uri, *p, *a, *na, *v; size_t len, l; FILE *stream = NULL; char pin[PINLEN + 1]; isc_boolean_t gotpin = ISC_FALSE; isc_result_t ret; /* get values to work on */ len = strlen(label) + 1; uri = isc_mem_get(mctx, len); if (uri == NULL) return (ISC_R_NOMEMORY); memmove(uri, label, len); /* get the URI scheme */ p = strchr(uri, ':'); if (p == NULL) DST_RET(PK11_R_NOPROVIDER); *p++ = '\0'; if (strcmp(uri, "pkcs11") != 0) DST_RET(PK11_R_NOPROVIDER); /* get attributes */ for (na = p; na != NULL;) { a = na; p = strchr(a, ';'); if (p == NULL) { /* last attribute */ na = NULL; } else { *p++ = '\0'; na = p; } p = strchr(a, '='); if (p != NULL) { *p++ = '\0'; v = p; } else v = a; l = 0; v = percent_decode(v, &l); if (v == NULL) DST_RET(PK11_R_NOPROVIDER); if ((a == v) || (strcmp(a, "object") == 0)) { /* object: CKA_LABEL */ attr = pk11_attribute_bytype(obj, CKA_LABEL); if (attr != NULL) DST_RET(PK11_R_NOPROVIDER); attr = push_attribute(obj, mctx, l); if (attr == NULL) DST_RET(ISC_R_NOMEMORY); attr->type = CKA_LABEL; memmove(attr->pValue, v, l); } else if (strcmp(a, "token") == 0) { /* token: CK_TOKEN_INFO label */ if (token == NULL) for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (pk11strcmp(v, l, token->name, 32)) break; } else if (strcmp(a, "manufacturer") == 0) { /* manufacturer: CK_TOKEN_INFO manufacturerID */ if (token == NULL) for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (pk11strcmp(v, l, token->manuf, 32)) break; } else if (strcmp(a, "serial") == 0) { /* serial: CK_TOKEN_INFO serialNumber */ if (token == NULL) for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (pk11strcmp(v, l, token->serial, 16)) break; } else if (strcmp(a, "model") == 0) { /* model: CK_TOKEN_INFO model */ if (token == NULL) for (token = ISC_LIST_HEAD(tokens); token != NULL; token = ISC_LIST_NEXT(token, link)) if (pk11strcmp(v, l, token->model, 16)) break; } else if (strcmp(a, "library-manufacturer") == 0) { /* ignored */ } else if (strcmp(a, "library-description") == 0) { /* ignored */ } else if (strcmp(a, "library-version") == 0) { /* ignored */ } else if (strcmp(a, "object-type") == 0) { /* object-type: CKA_CLASS */ /* only private makes sense */ if (strcmp(v, "private") != 0) DST_RET(PK11_R_NOPROVIDER); } else if (strcmp(a, "id") == 0) { /* id: CKA_ID */ attr = pk11_attribute_bytype(obj, CKA_ID); if (attr != NULL) DST_RET(PK11_R_NOPROVIDER); attr = push_attribute(obj, mctx, l); if (attr == NULL) DST_RET(ISC_R_NOMEMORY); attr->type = CKA_ID; memmove(attr->pValue, v, l); } else if (strcmp(a, "pin-source") == 0) { /* pin-source: PIN */ ret = isc_stdio_open(v, "r", &stream); if (ret != ISC_R_SUCCESS) goto err; memset(pin, 0, PINLEN + 1); ret = isc_stdio_read(pin, 1, PINLEN + 1, stream, &l); if ((ret != ISC_R_SUCCESS) && (ret != ISC_R_EOF)) goto err; if (l > PINLEN) DST_RET(ISC_R_RANGE); ret = isc_stdio_close(stream); stream = NULL; if (ret != ISC_R_SUCCESS) goto err; gotpin = ISC_TRUE; } else DST_RET(PK11_R_NOPROVIDER); } if ((pk11_attribute_bytype(obj, CKA_LABEL) == NULL) && (pk11_attribute_bytype(obj, CKA_ID) == NULL)) DST_RET(ISC_R_NOTFOUND); if (token == NULL) { if (optype == OP_RSA) token = best_rsa_token; else if (optype == OP_DSA) token = best_dsa_token; else if (optype == OP_DH) token = best_dh_token; else if (optype == OP_EC) token = best_ec_token; } if (token == NULL) DST_RET(ISC_R_NOTFOUND); obj->slot = token->slotid; if (gotpin) { memmove(token->pin, pin, PINLEN + 1); obj->reqlogon = ISC_TRUE; } ret = ISC_R_SUCCESS; err: if (stream != NULL) (void) isc_stdio_close(stream); isc_mem_put(mctx, uri, len); return (ret); }
static void test_percent_decode_no_entities(void **state) { char *test = "hello world"; assert_true(percent_decode(test)); assert_string_equal("hello world", test); }
static void test_percent_decode(void **state) { char *test = strdup("hello%20world"); assert_true(percent_decode(test)); assert_string_equal(test, "hello world"); free(test); }
static void test_percent_decode_failure(void **state) { char *test = "hello %world"; assert_false(percent_decode(test)); }
/* * Initializes an OATH key with the parameters from a Google otpauth URI. * * https://github.com/google/google-authenticator/wiki/Key-Uri-Format */ int oath_key_from_uri(oath_key *key, const char *uri) { char name[64], value[256]; size_t namelen, valuelen; const char *p, *q, *r; uintmax_t n; char *e; memset(key, 0, sizeof *key); /* check method */ p = uri; if (strlcmp("otpauth://", p, 10) != 0) goto invalid; p += 10; /* check mode (hotp = event, totp = time-sync) */ if ((q = strchr(p, '/')) == NULL) goto invalid; if (strlcmp("hotp", p, q - p) == 0) { key->mode = om_hotp; } else if (strlcmp("totp", p, q - p) == 0) { key->mode = om_totp; } else { goto invalid; } p = q + 1; /* extract label */ if ((q = strchr(p, '?')) == NULL) goto invalid; key->labellen = sizeof key->label; if (percent_decode(p, q - p, key->label, &key->labellen) != 0) goto invalid; p = q + 1; /* extract parameters */ key->counter = UINT64_MAX; key->lastused = UINT64_MAX; while (*p != '\0') { /* locate name-value separator */ if ((q = strchr(p, '=')) == NULL) goto invalid; q = q + 1; /* locate end of value */ if ((r = strchr(p, '&')) == NULL) r = strchr(p, '\0'); if (r < q) /* & before = */ goto invalid; /* decode name and value*/ namelen = sizeof name; valuelen = sizeof value; if (percent_decode(p, q - p - 1, name, &namelen) != 0 || percent_decode(q, r - q, value, &valuelen) != 0) goto invalid; if (strcmp("secret", name) == 0) { if (key->keylen != 0) /* dupe */ goto invalid; key->keylen = sizeof key->key; if (base32_decode(value, valuelen, key->key, &key->keylen) != 0) goto invalid; } else if (strcmp("algorithm", name) == 0) { if (key->hash != oh_undef) /* dupe */ goto invalid; if (strcmp("SHA1", value) == 0) key->hash = oh_sha1; else if (strcmp("SHA256", value) == 0) key->hash = oh_sha256; else if (strcmp("SHA512", value) == 0) key->hash = oh_sha512; else if (strcmp("MD5", value) == 0) key->hash = oh_md5; else goto invalid; } else if (strcmp("digits", name) == 0) { if (key->digits != 0) /* dupe */ goto invalid; n = strtoumax(value, &e, 10); if (e == value || *e != '\0' || n < OATH_MIN_DIGITS || n > OATH_MAX_DIGITS) goto invalid; key->digits = n; } else if (strcmp("counter", name) == 0) { if (key->counter != UINT64_MAX) /* dupe */ goto invalid; n = strtoumax(value, &e, 10); if (e == value || *e != '\0' || n >= UINT64_MAX) goto invalid; key->counter = (uint64_t)n; } else if (strcmp("lastused", name) == 0) { if (key->lastused != UINT64_MAX) /* dupe */ goto invalid; n = strtoumax(value, &e, 10); if (e == value || *e != '\0' || n >= UINT64_MAX) goto invalid; key->lastused = (uint64_t)n; } else if (strcmp("period", name) == 0) { if (key->timestep != 0) /* dupe */ goto invalid; n = strtoumax(value, &e, 10); if (e == value || *e != '\0' || n > OATH_MAX_TIMESTEP) goto invalid; key->timestep = n; } else if (strcmp("issuer", name) == 0) { key->issuerlen = strlcpy(key->issuer, value, sizeof key->issuer); if (key->issuerlen >= sizeof key->issuer) goto invalid; } else { goto invalid; } /* final parameter? */ if (*r == '\0') break; /* skip & and continue */ p = r + 1; } /* sanity checks and default values */ if (key->mode == om_hotp) { if (key->counter == UINT64_MAX) key->counter = 0; if (key->timestep != 0) goto invalid; if (key->lastused != UINT64_MAX) goto invalid; } else if (key->mode == om_totp) { if (key->counter != UINT64_MAX) goto invalid; if (key->timestep == 0) key->timestep = OATH_DEF_TIMESTEP; if (key->lastused == UINT64_MAX) key->lastused = 0; } else { /* unreachable */ goto invalid; } if (key->hash == oh_undef) key->hash = oh_sha1; if (key->digits == 0) key->digits = 6; if (key->keylen == 0) goto invalid; return (0); invalid: memset(key, 0, sizeof *key); return (-1); }
void request_parser::parse_content(request& req) { if (req.content.empty()) { return; } std::string standard_type = "application/x-www-form-urlencoded"; std::string multipart_type = "multipart/form-data"; std::string content_type = req.header("Content-Type"); if (content_type.empty() || strings_are_equal(content_type, standard_type, standard_type.size())) { std::string name, value; std::string::size_type pos; std::string::size_type old_pos = 0; while (true) { pos = req.content.find_first_of("&=", old_pos); if (pos == std::string::npos) { break; } if (req.content.at(pos) == '&') { const char* c_str_ = req.content.c_str() + old_pos; while (*c_str_ == '&') { ++c_str_; ++old_pos; } if (old_pos >= pos) { old_pos = ++pos; continue; } name = percent_decode(req.content.substr(old_pos, pos - old_pos)); req.params.push_back(name_value(name, std::string())); old_pos = ++pos; continue; } name = percent_decode(req.content.substr(old_pos, pos - old_pos)); old_pos = ++pos; pos = req.content.find_first_of(";&", old_pos); value = percent_decode(req.content.substr(old_pos, pos - old_pos)); req.params.push_back(name_value(name, value)); if (pos == std::string::npos) { break; } old_pos = ++pos; } } else if (strings_are_equal(multipart_type, content_type, multipart_type.size())) { std::string b_type = "boundary="; std::string::size_type pos = content_type.find(b_type); std::string sep1 = content_type.substr(pos + b_type.size()); if (sep1.find(";") != std::string::npos) { sep1 = sep1.substr(0, sep1.find(";")); } sep1.append("\r\n"); sep1.insert(0, "--"); std::string sep2 = content_type.substr(pos + b_type.size()); if (sep2.find(";") != std::string::npos) { sep2 = sep2.substr(0, sep2.find(";")); } sep2.append("--\r\n"); sep2.insert(0, "--"); std::string::size_type start = req.content.find(sep1); std::string::size_type sep_size = sep1.size(); std::string::size_type old_pos = start + sep_size; while (true) { pos = req.content.find(sep1, old_pos); if (pos == std::string::npos) { break; } parse_multipart_content(req, req.content.substr(old_pos, pos - old_pos)); old_pos = pos + sep_size; } pos = req.content.find(sep2, old_pos); if (pos != std::string::npos) { parse_multipart_content(req, req.content.substr(old_pos, pos - old_pos)); } } }