static void test_skip_quoted(void) { char x[] = "a=1, b=2 c='hi \' there'", *s = x, *p; p = skip_quoted(&s, ", ", ", ", 0); ASSERT(p != NULL && !strcmp(p, "a=1")); p = skip_quoted(&s, ", ", ", ", 0); ASSERT(p != NULL && !strcmp(p, "b=2")); // TODO(lsm): fix this #if 0 p = skip_quoted(&s, "'", ", ", '\\'); p = skip_quoted(&s, "'", ", ", '\\'); printf("[%s]\n", p); ASSERT(p != NULL && !strcmp(p, "hi ' there")); #endif }
static int end_of_comment(int curpos) { curpos+=2; while(cbuf[curpos]!=0) { if(cbuf[curpos]=='*' && cbuf[curpos+1]=='/') return curpos+2; if(cbuf[curpos]=='\'') { curpos+=skip_quoted(cbuf+curpos,'\''); continue; } if(cbuf[curpos]=='\"') { curpos+=skip_quoted(cbuf+curpos,'\"'); continue; } curpos++; } return curpos; }
/** Skip to the next newline or comment that is not part of a quoted * string. When ELinks hits a parse error in the configuration file, * it calls this in order to find the place where is should resume * parsing. This is intended to prevent ELinks from treating words * in strings as commands. */ static void skip_to_unquoted_newline_or_comment(struct conf_parsing_pos *pos) { while (*pos->look && *pos->look != '#' && *pos->look != '\n') { if (isquote(*pos->look)) skip_quoted(pos); else pos->look++; } }
// Parse HTTP headers from the given buffer, advance buffer to the point // where parsing stopped. static void parse_http_headers(char **buf, struct mg_request_info *ri) { int i; for (i = 0; i < (int) ARRAY_SIZE(ri->http_headers); i++) { ri->http_headers[i].name = skip_quoted(buf, ":", " ", 0); ri->http_headers[i].value = skip(buf, "\r\n"); if (ri->http_headers[i].name[0] == '\0') break; ri->num_headers = i + 1; } }
/** Skip the value of an option. * * This job is normally done by the reader function that corresponds * to the type of the option. However, if ELinks does not recognize * the name of the option, it cannot look up the type and has to use * this function instead. */ static void skip_option_value(struct conf_parsing_pos *pos) { if (isquote(*pos->look)) { /* Looks like OPT_STRING, OPT_CODEPAGE, OPT_LANGUAGE, * or OPT_COLOR. */ skip_quoted(pos); } else { /* Looks like OPT_BOOL, OPT_INT, or OPT_LONG. */ while (isasciialnum(*pos->look) || *pos->look == '.' || *pos->look == '+' || *pos->look == '-') pos->look++; } }
END_TEST START_TEST(test_skip_quoted) { /* Adapted from unit_test.c */ /* Copyright (c) 2013-2015 the Civetweb developers */ /* Copyright (c) 2004-2013 Sergey Lyubka */ char x[] = "a=1, b=2, c='hi \' there', d='here\\, there'", *s = x, *p; p = skip_quoted(&s, ", ", ", ", 0); ck_assert(p != NULL && !strcmp(p, "a=1")); p = skip_quoted(&s, ", ", ", ", 0); ck_assert(p != NULL && !strcmp(p, "b=2")); p = skip_quoted(&s, ",", " ", 0); ck_assert(p != NULL && !strcmp(p, "c='hi \' there'")); p = skip_quoted(&s, ",", " ", '\\'); ck_assert(p != NULL && !strcmp(p, "d='here, there'")); ck_assert(*s == 0); }
static HTTP_HEADER * parse_http_headers (unsigned char **buf, int *num_headers) { int i; HTTP_HEADER *hdrs; char *hdr_end; errno_t safec_rc; *num_headers = 0; hdrs = malloc(sizeof(HTTP_HEADER) * MAX_HEADERS); if (!hdrs) { EST_LOG_ERR("malloc failure"); return (NULL); } /* * Find offset of header deliminter */ safec_rc = strstr_s((char *) *buf, strnlen_s((char *) *buf, RSIZE_MAX_STR), "\r\n\r\n", MAX_HEADER_DELIMITER_LEN, &hdr_end); if (safec_rc != EOK) { EST_LOG_INFO("strstr_s error 0x%xO\n", safec_rc); } /* * Skip the first line */ skip((char **)buf, "\r\n"); for (i = 0; i < MAX_HEADERS; i++) { hdrs[i].name = skip_quoted((char **)buf, ":", " ", 0); hdrs[i].value = skip((char **)buf, "\r\n"); fflush(stdout); EST_LOG_INFO("Found HTTP header -> %s:%s", hdrs[i].name, hdrs[i].value); fflush(stdout); if (hdrs[i].name[0] == '\0') { break; } *num_headers = i + 1; if ((*buf) > (unsigned char *)hdr_end) { break; } } EST_LOG_INFO("Found %d HTTP headers\n", *num_headers); return (hdrs); }
static HTTP_HEADER * parse_http_headers (unsigned char **buf, int *num_headers) { int i; HTTP_HEADER *hdrs; char *hdr_end; *num_headers = 0; hdrs = malloc(sizeof(HTTP_HEADER) * MAX_HEADERS); if (!hdrs) { EST_LOG_ERR("malloc failure"); return (NULL); } /* * Find offset of header delimiter */ hdr_end = strstr((const char *)*buf, "\r\n\r\n"); /* * Skip the first line */ skip((char **)buf, "\r\n"); for (i = 0; i < MAX_HEADERS; i++) { hdrs[i].name = skip_quoted((char **)buf, ":", " ", 0); hdrs[i].value = skip((char **)buf, "\r\n"); EST_LOG_INFO("Found HTTP header -> %s: %s", hdrs[i].name, hdrs[i].value); if (hdrs[i].name[0] == '\0') { break; } *num_headers = i + 1; if ((*buf) > (unsigned char *)hdr_end) { break; } } EST_LOG_INFO("Found %d HTTP headers", *num_headers); return (hdrs); }
// Simplified version of skip_quoted without quote char // and whitespace == delimiters static char *skip(char **buf, const char *delimiters) { return skip_quoted(buf, delimiters, delimiters, 0); }
// Return 1 on success. Always initializes the ah structure. static int parse_auth_header(struct mg_connection *conn, char *buf, size_t buf_size, struct ah *ah) { char *name, *value, *s; const char *auth_header; (void) memset(ah, 0, sizeof(*ah)); if ((auth_header = mg_get_header(conn, "Authorization")) == NULL || mg_strncasecmp(auth_header, "Digest ", 7) != 0) { return 0; } // Make modifiable copy of the auth header (void) mg_strlcpy(buf, auth_header + 7, buf_size); s = buf; // Parse authorization header for (;;) { // Gobble initial spaces while (isspace(* (unsigned char *) s)) { s++; } name = skip_quoted(&s, "=", " ", 0); // Value is either quote-delimited, or ends at first comma or space. if (s[0] == '\"') { s++; value = skip_quoted(&s, "\"", " ", '\\'); if (s[0] == ',') { s++; } } else { value = skip_quoted(&s, ", ", " ", 0); // IE uses commas, FF uses spaces } if (*name == '\0') { break; } if (!strcmp(name, "username")) { ah->user = value; } else if (!strcmp(name, "cnonce")) { ah->cnonce = value; } else if (!strcmp(name, "response")) { ah->response = value; } else if (!strcmp(name, "uri")) { ah->uri = value; } else if (!strcmp(name, "qop")) { ah->qop = value; } else if (!strcmp(name, "nc")) { ah->nc = value; } else if (!strcmp(name, "nonce")) { ah->nonce = value; } } // CGI needs it as REMOTE_USER if (ah->user != NULL) { conn->request_info.remote_user = mg_strdup(ah->user); } else { return 0; } return 1; }