예제 #1
0
    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;
    }
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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
}
예제 #6
0
    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;
    }
예제 #7
0
파일: chunk.cpp 프로젝트: chtq/via-httplib
    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;
    }
예제 #8
0
/* 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;
}
예제 #9
0
static char *
skip_spaces(char *s) {
	while (is_space_or_tab(*s))
		s++;
	return s;
}
예제 #10
0
    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;
    }