Example #1
0
static int methodline_parse(struct buffer *bu, struct methodline_state *ms,
	struct buffer *method, struct buffer *uri, struct buffer *version)
{
	const char *s = bu->data;
	unsigned rem = bu->cur;
	char ch;

	while (rem > 0) {
		ch = *s;
		s++;
		rem--;

		switch (ms->state) {
		case 0: /* method */
			if (ch == ' ')
				ms->state = 1;
			else
				buffer_addch(method, ch);
			break;
		case 1: /* uri */
			if (ch == ' ')
				ms->state = 2;
			else
				buffer_addch(uri, ch);
			break;
		case 2: /* version */
			if (ch == '\r')
				ms->state = 3;
			else if (isspace(ch))
				goto parse_error;
			else
				buffer_addch(version, ch);
			break;
		case 3: /* CR */
			if (ch == '\n')
				goto complete;
			else
				goto parse_error;
			break;
		default:
			assert(0);
		}
	}

	buffer_consume(bu, s - bu->data);
	return 0;
complete:
	ms->done = true;
	buffer_consume(bu, s - bu->data);
	return 0;
parse_error:
	Error("%s():parse failure (%.*s)\n",
		__func__, bu->cur, bu->data);
	buffer_consume(bu, s - bu->data);
	Error("%s():parse failure @ %d (state=%d)\n",
		__func__, bu->cur, ms->state);
	return -1;
}
Example #2
0
static int _csv_escaped_dquote(struct csv_parser *cp)
{
    if (buffer_addch(&cp->buf, '"'))
        return -1;
    cp->s = CSV_ESCAPED;
    return 0;
}
Example #3
0
static int headers_parse(struct buffer *bu, struct headers_state *hs,
	struct buffer *name, struct buffer *value, struct env *env)
{
	const char *s = bu->data;
	unsigned rem = bu->cur;
	char ch;

	// TODO: 413 Entity Too Large
	while (rem > 0) {
		ch = *s;
		s++;
		rem--;

		switch (hs->state) {
		case 0: /* first char */
			if (ch == '\r') {
				if (name->cur)
					env_set(env, name->data, value->data);
				hs->state = 6; /* CR/LF - end of headers */
			} else if (ch == ' ' || ch == '\t') { /* indented continuation line */
				// TODO: this is completely untested .. device a test for it!
				// TODO: insert single SP for these leading LWS
				hs->state = 4; /* append to existing value data */
			} else {
				if (name->cur)
					env_set(env, name->data, value->data);
				buffer_reset(name);
				buffer_reset(value);
				buffer_addch(name, ch);
				hs->state = 11;
			}
			break;
		case 11: /* name */
			if (ch == ' ' || ch == '\t') { /* LWS after name */
				hs->state = 1;
			} else if (ch == ':') {
				hs->state = 2;
			} else if (isspace(ch)) {
				goto parse_error;
			} else {
				buffer_addch(name, ch);
			}
			break;
		case 1: /* LWS after name */
			if (ch == ' ' || ch == '\t')
				; /* ignore */
			else if (ch == ':')
				hs->state = 2;
			else
				goto parse_error;
			break;
		case 2: /* ':' */
			if (ch == ' ' || ch == '\t') {
				hs->state = 3;
			} else {
				buffer_addch(value, ch);
				hs->state = 4;
			}
			break;
		case 3: /* LWS before value */
			if (ch == ' ' || ch == '\t') {
				/* ignore */
			} else if (isspace(ch)) {
				goto parse_error;
			} else {
				buffer_addch(value, ch);
				hs->state = 4;
			}
			break;
		case 4: /* value */
			if (ch == '\r')
				hs->state = 5;
			else
				buffer_addch(value, ch);
			break;
		case 5: /* CR after value */
			if (ch == '\n')
				hs->state = 0;
			else
				goto parse_error;
			break;
		case 6: /* CR on first column */
			if (ch == '\n')
				goto complete;
			else
				goto parse_error;
			break;
		default:
			assert(0);
		}
	}

	buffer_consume(bu, s - bu->data);
	return 0;
complete:
	hs->done = true;
	buffer_consume(bu, s - bu->data);
	return 0;
parse_error:
	Error("%s():parse failure (%.*s)\n",
		__func__, bu->cur, bu->data);
	buffer_consume(bu, s - bu->data);
	Error("%s():parse failure @ %d (ch=%c state=%d)\n",
		__func__, bu->cur, ch, hs->state);
	return -1;
}
Example #4
0
static int csv(struct csv_parser *cp, const char *buf, size_t len)
{
    while (len > 0) {
        char ch = *buf;

        buf++;
        len--;
        switch (cp->s) {
        case CSV_START:
            if (ch == '\r')
                cp->s = CSV_NEWLINE;
            else if (ch == '\n')
                _csv_next_row(cp);
            else if (ch == '"')
                cp->s = CSV_ESCAPED;
            else if (ch == ',')
                _csv_next_field(cp);
            else
                goto unescaped;
            break;
        case CSV_ESCAPED:
            if (ch == '"')
                cp->s = CSV_ESCAPED_DQUOTE;
            else if (buffer_addch(&cp->buf, ch))
                return -1;
            break;
        case CSV_ESCAPED_DQUOTE:
            if (ch == '\r')
                cp->s = CSV_NEWLINE;
            else if (ch == '\n')
                _csv_next_row(cp);
            else if (ch == '"') {
                if (_csv_escaped_dquote(cp))
                    return -1;
            } else if (ch == ',')
                _csv_next_field(cp);
            else
                goto unescaped; /* deviates from RFC 4180 */
            break;
unescaped:
            cp->s = CSV_UNESCAPED;
        case CSV_UNESCAPED:
            if (ch == '\r')
                cp->s = CSV_NEWLINE;
            else if (ch == '\n')
                _csv_next_row(cp);
            else if (ch == '"')
                cp->s = CSV_ESCAPED; /* deviates from RFC 4180 */
            else if (ch == ',')
                _csv_next_field(cp);
            else if (buffer_addch(&cp->buf, ch))
                return -1;
            break;
        case CSV_NEWLINE:
            if (ch == '\n')
                _csv_next_row(cp);
            else
                return -1;
        case CSV_ERROR:
            return -1;
        }
    }
    return cp->s == CSV_ERROR ? -1 : 0;
}