bool cookie::parse_char(char c, std::string& name, std::string& value) { std::string* name_ptr = &name; std::string* value_ptr = &value; auto value_state = COOKIE_ATTR_VALUE; switch (state_) { case COOKIE_NAME: name_ptr = &name_; value_state = COOKIE_VALUE; case COOKIE_ATTR_NAME: if (std::isalpha(c) || ('-' == c)) name_ptr->push_back(static_cast<char>(std::tolower(c))); else if ('=' == c) state_ = value_state; else if (!is_space_or_tab(c)) return false; break; case COOKIE_VALUE: value_ptr = &value_; case COOKIE_ATTR_VALUE: if (';' == c && state_ == COOKIE_ATTR_VALUE) { parse_attr(name, value); state_ = COOKIE_ATTR_NAME; } else if (!is_space_or_tab(c)) value_ptr->push_back(c); break; default: return false; } return true; }
static bool cf_lexer_is_include(struct cf_lexer *lex) { bool found_include_import = false; bool found_preprocessor = false; size_t i; for (i = lex->tokens.num; i > 0; i--) { struct cf_token *token = lex->tokens.array+(i-1); if (is_space_or_tab(*token->str.array)) continue; if (!found_include_import) { if (strref_cmp(&token->str, "include") != 0 && strref_cmp(&token->str, "import") != 0) break; found_include_import = true; } else if (!found_preprocessor) { if (*token->str.array != '#') break; found_preprocessor = true; } else { return is_newline(*token->str.array); } } /* if starting line */ return found_preprocessor && found_include_import; }
bool cf_lexer_lex(struct cf_lexer *lex, const char *str, const char *file) { struct cf_token token; struct cf_token *last_token = NULL; cf_lexer_free(lex); if (!str || !*str) return false; if (file) lex->file = bstrdup(file); lexer_start(&lex->base_lexer, str); cf_token_clear(&token); lex->reformatted = bmalloc(strlen(str) + 1); lex->reformatted[0] = 0; lex->write_offset = lex->reformatted; while (cf_lexer_nexttoken(lex, &token)) { if (last_token && is_space_or_tab(*last_token->str.array) && is_space_or_tab(*token.str.array)) { cf_token_add(last_token, &token); continue; } token.lex = lex; last_token = da_push_back_new(lex->tokens); memcpy(last_token, &token, sizeof(struct cf_token)); } cf_token_clear(&token); token.str.array = lex->write_offset; token.unmerged_str.array = lex->base_lexer.offset; token.lex = lex; da_push_back(lex->tokens, &token); return !lex->unexpected_eof; }
static bool cf_is_token_break(struct base_token *start_token, const struct base_token *token) { switch (start_token->type) { case BASETOKEN_ALPHA: if (token->type == BASETOKEN_OTHER || token->type == BASETOKEN_WHITESPACE) return true; break; case BASETOKEN_DIGIT: if (token->type == BASETOKEN_WHITESPACE || (token->type == BASETOKEN_OTHER && *token->text.array != '.')) return true; break; case BASETOKEN_WHITESPACE: /* lump all non-newline whitespace together when possible */ if (is_space_or_tab(*start_token->text.array) && is_space_or_tab(*token->text.array)) break; return true; case BASETOKEN_OTHER: if (*start_token->text.array == '.' && token->type == BASETOKEN_DIGIT) { start_token->type = BASETOKEN_DIGIT; break; } case BASETOKEN_NONE: return true; } return false; }
int mailimap_space_parse(mailstream * fd, MMAPString * buffer, size_t * indx) { #ifdef UNSTRICT_SYNTAX /* can accept unstrict syntax */ size_t cur_token; cur_token = * indx; while (is_space_or_tab(* (buffer->str + cur_token))) cur_token ++; if (cur_token == * indx) return MAILIMAP_ERROR_PARSE; * indx = cur_token; return MAILIMAP_NO_ERROR; #else return mailimap_char_parse(fd, buffer, indx, ' '); #endif }
bool field_line::parse_char(char c) { // Ensure that the overall header length is within limitts if (++length_ > max_line_length_) state_ = HEADER_ERROR_LENGTH; switch (state_) { case HEADER_NAME: if (std::isalpha(c) || ('-' == c)) name_.push_back(static_cast<char>(std::tolower(c))); else if (':' == c) state_ = HEADER_VALUE_LS; else return false; break; case HEADER_VALUE_LS: // Ignore leading whitespace if (is_space_or_tab(c)) // but only upto to a limit! if (++ws_count_ > max_whitespace_) { state_ = HEADER_ERROR_WS; return false; } else break; else state_ = HEADER_VALUE; [[fallthrough]]; // intentional fall-through case HEADER_VALUE: // The header line should end with an \r\n... if (!is_end_of_line(c)) value_.push_back(c); else if ('\r' == c) state_ = HEADER_LF; else // ('\n' == c) { if (strict_crlf_) { state_ = HEADER_ERROR_CRLF; return false; } else state_ = HEADER_VALID; } break; case HEADER_LF: if ('\n' == c) state_ = HEADER_VALID; else return false; break; default: return false; } return true; }
bool chunk_header::parse_char(char c) { static const size_t MAX_SIZE_DIGITS(16); // enough for a 64 bit number // Ensure that the overall header length is within limits if (++length_ > max_line_length_) state_ = CHUNK_ERROR_LENGTH; switch (state_) { case CHUNK_SIZE_LS: // Ignore leading whitespace if (is_space_or_tab(c)) { // but only upto to a limit! if (++ws_count_ > max_whitespace_) { state_ = CHUNK_ERROR_WS; return false; } else break; } else state_ = CHUNK_SIZE; // intentional fall-through case CHUNK_SIZE: if (std::isxdigit (c)) { hex_size_.push_back(c); // limit the length of the hex string if (hex_size_.size() > MAX_SIZE_DIGITS) { state_ = CHUNK_ERROR_SIZE; return false; } } else { if (is_end_of_line(c) || (';' == c)) { size_ = from_hex_string(hex_size_); size_read_ = true; if (size_ > max_chunk_size_) { state_ = CHUNK_ERROR_SIZE; return false; } if (';' == c) { ws_count_ = 0; state_ = CHUNK_EXTENSION_LS; } else { if ('\r' == c) state_ = CHUNK_LF; else // ('\n' == c) { if (strict_crlf_) return false; else state_ = CHUNK_VALID; } } } else return false; } break; case CHUNK_EXTENSION_LS: // Ignore leading whitespace if (is_space_or_tab(c)) { // but only upto to a limit! if (++ws_count_ > max_whitespace_) return false; else break; } else state_ = CHUNK_EXTENSION; // intentional fall-through case CHUNK_EXTENSION: if (!is_end_of_line(c)) extension_.push_back(c); else if ('\r' == c) state_ = CHUNK_LF; else // ('\n' == c) { if (strict_crlf_) { state_ = CHUNK_ERROR_CRLF; return false; } else state_ = CHUNK_VALID; } break; case CHUNK_LF: if ('\n' == c) state_ = CHUNK_VALID; else return false; break; default: return false; } return true; }
/* Read the next entry from the file fp. Stop reading at an incorrect entry. */ struct my_mntent * my_getmntent (mntFILE *mfp) { static char buf[4096]; static struct my_mntent me; char *s; again: if (mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX) return NULL; /* read the next non-blank non-comment line */ do { if (fgets (buf, sizeof(buf), mfp->mntent_fp) == NULL) return NULL; mfp->mntent_lineno++; s = strchr (buf, '\n'); if (s == NULL) { /* Missing final newline? Otherwise extremely */ /* long line - assume file was corrupted */ if (feof(mfp->mntent_fp)) { fprintf(stderr, _("[mntent]: warning: no final " "newline at the end of %s\n"), mfp->mntent_file); s = strchr (buf, 0); } else { mfp->mntent_errs = 1; goto err; } } *s = 0; if (--s >= buf && *s == '\r') *s = 0; s = skip_spaces(buf); } while (*s == '\0' || *s == '#'); me.mnt_fsname = unmangle(s, &s); s = skip_spaces(s); me.mnt_dir = unmangle(s, &s); s = skip_spaces(s); me.mnt_type = unmangle(s, &s); s = skip_spaces(s); me.mnt_opts = unmangle(s, &s); s = skip_spaces(s); if (!me.mnt_fsname || !me.mnt_dir || !me.mnt_type) goto err; if (isdigit(*s)) { me.mnt_freq = atoi(s); while(isdigit(*s)) s++; } else me.mnt_freq = 0; if(*s && !is_space_or_tab(*s)) goto err; s = skip_spaces(s); if(isdigit(*s)) { me.mnt_passno = atoi(s); while(isdigit(*s)) s++; } else me.mnt_passno = 0; if(*s && !is_space_or_tab(*s)) goto err; /* allow more stuff, e.g. comments, on this line */ return &me; err: mfp->mntent_softerrs++; fprintf(stderr, _("[mntent]: line %d in %s is bad%s\n"), mfp->mntent_lineno, mfp->mntent_file, (mfp->mntent_errs || mfp->mntent_softerrs >= ERR_MAX) ? _("; rest of file ignored") : ""); goto again; }
static char * skip_spaces(char *s) { while (is_space_or_tab(*s)) s++; return s; }
bool request_line::parse_char(char c) { switch (state_) { case REQ_METHOD: // Valid HTTP methods must be uppercase chars if (std::isupper(c)) { method_.push_back(c); if (method_.size() > max_method_length_) { state_ = REQ_ERROR_METHOD_LENGTH; return false; } } // If this char is whitespace and method has been read else if (is_space_or_tab(c) && !method_.empty()) { ws_count_ = 1; state_ = REQ_URI; } else return false; break; case REQ_URI: if (is_end_of_line(c)) return false; else if (is_space_or_tab(c)) { // Ignore leading whitespace // but only upto to a limit! if (++ws_count_ > max_whitespace_) { state_ = REQ_ERROR_WS; return false; } if (!uri_.empty()) { ws_count_ = 1; state_ = REQ_HTTP_H; } } else { uri_.push_back(c); if (uri_.size() > max_uri_length_) { state_ = REQ_ERROR_URI_LENGTH; return false; } } break; case REQ_HTTP_H: // Ignore leading whitespace if (is_space_or_tab(c)) { // but only upto to a limit! if (++ws_count_ > max_whitespace_) { state_ = REQ_ERROR_WS; return false; } } else { if ('H' == c) state_ = REQ_HTTP_T1; else return false; } break; case REQ_HTTP_T1: if ('T' == c) state_ = REQ_HTTP_T2; else return false; break; case REQ_HTTP_T2: if ('T' == c) state_ = REQ_HTTP_P; else return false; break; case REQ_HTTP_P: if ('P' == c) state_ = REQ_HTTP_SLASH; else return false; break; case REQ_HTTP_SLASH: if ('/' == c) state_ = REQ_HTTP_MAJOR; else return false; break; case REQ_HTTP_MAJOR: if (std::isdigit(c)) { major_version_ = c; state_ = REQ_HTTP_DOT; } else return false; break; case REQ_HTTP_DOT: if ('.' == c) state_ = REQ_HTTP_MINOR; else return false; break; case REQ_HTTP_MINOR: if (std::isdigit(c)) { minor_version_ = c; state_ = REQ_CR; } else return false; break; case REQ_CR: // The HTTP line should end with a \r\n... if ('\r' == c) state_ = REQ_LF; else { // but (if not being strict) permit just \n if (!strict_crlf_ && ('\n' == c)) state_ = REQ_VALID; else { state_ = REQ_ERROR_CRLF; return false; } } break; case REQ_LF: if ('\n' == c) { state_ = REQ_VALID; break; } // intentional fall-through (for code coverage) default: return false; } return true; }