Exemplo n.º 1
0
static const char* is_complete(const char* buf, const char* buf_end,
                               size_t last_len, int* ret)
{
  int ret_cnt = 0;
  buf = last_len < 3 ? buf : buf + last_len - 3;
  
  while (1) {
    CHECK_EOF();
    if (*buf == '\015') {
      ++buf;
      CHECK_EOF();
      EXPECT_CHAR('\012');
      ++ret_cnt;
    } else if (*buf == '\012') {
      ++buf;
      ++ret_cnt;
    } else {
      ++buf;
      ret_cnt = 0;
    }
    if (ret_cnt == 2) {
      return buf;
    }
  }
  
  *ret = -2;
  return NULL;
}
Exemplo n.º 2
0
static int is_complete(const char* buf, const char* buf_end, size_t last_len)
{
  int ret_cnt = 0;
  buf = last_len < 3 ? buf : buf + last_len - 3;
  
  while (1) {
    CHECK_EOF();
    if (*buf == '\r') {
      ++buf;
      CHECK_EOF();
      EXPECT('\n');
      ++ret_cnt;
    } else if (*buf == '\n') {
      ++buf;
      ++ret_cnt;
    } else {
      ++buf;
      ret_cnt = 0;
    }
    if (ret_cnt == 2) {
      return 0;
    }
  }
  
  return -2;
}
Exemplo n.º 3
0
static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, size_t *num_headers,
                                 size_t max_headers, int *ret)
{
    for (;; ++*num_headers) {
        CHECK_EOF();
        if (*buf == '\015') {
            ++buf;
            EXPECT_CHAR('\012');
            break;
        } else if (*buf == '\012') {
            ++buf;
            break;
        }
        if (*num_headers == max_headers) {
            *ret = -1;
            return NULL;
        }
        if (!(*num_headers != 0 && (*buf == ' ' || *buf == '\t'))) {
            if (!token_char_map[(unsigned char)*buf]) {
                *ret = -1;
                return NULL;
            }
            /* parsing name, but do not discard SP before colon, see
             * http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */
            headers[*num_headers].name = buf;
            static const char ALIGNED(16) ranges1[] = "::\x00\037";
            int found;
            buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found);
            if (!found) {
                CHECK_EOF();
            }
            while (1) {
                if (*buf == ':') {
                    break;
                } else if (*buf < ' ') {
                    *ret = -1;
                    return NULL;
                }
                ++buf;
                CHECK_EOF();
            }
            headers[*num_headers].name_len = buf - headers[*num_headers].name;
            ++buf;
            for (;; ++buf) {
                CHECK_EOF();
                if (!(*buf == ' ' || *buf == '\t')) {
                    break;
                }
            }
        } else {
            headers[*num_headers].name = NULL;
            headers[*num_headers].name_len = 0;
        }
        if ((buf = get_token_to_eol(buf, buf_end, &headers[*num_headers].value, &headers[*num_headers].value_len, ret)) == NULL) {
            return NULL;
        }
    }
Exemplo n.º 4
0
static const char *parse_headers(const char *buf, const char *buf_end, struct phr_header *headers, size_t *num_headers,
                                 size_t max_headers, int *ret)
{
    for (;; ++*num_headers) {
        CHECK_EOF();
        if (*buf == '\015') {
            ++buf;
            EXPECT_CHAR('\012');
            break;
        } else if (*buf == '\012') {
            ++buf;
            break;
        }
        if (*num_headers == max_headers) {
            *ret = -1;
            return NULL;
        }
        if (!(*num_headers != 0 && (*buf == ' ' || *buf == '\t'))) {
            /* parsing name, but do not discard SP before colon, see
             * http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */
            headers[*num_headers].name = buf;
            static const char ALIGNED(16) ranges1[] = "\x00 "  /* control chars and up to SP */
                                                      "\"\""   /* 0x22 */
                                                      "()"     /* 0x28,0x29 */
                                                      ",,"     /* 0x2c */
                                                      "//"     /* 0x2f */
                                                      ":@"     /* 0x3a-0x40 */
                                                      "[]"     /* 0x5b-0x5d */
                                                      "{\377"; /* 0x7b-0xff */
            int found;
            buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found);
            if (!found) {
                CHECK_EOF();
            }
            while (1) {
                if (*buf == ':') {
                    break;
                } else if (!token_char_map[(unsigned char)*buf]) {
                    *ret = -1;
                    return NULL;
                }
                ++buf;
                CHECK_EOF();
            }
            if ((headers[*num_headers].name_len = buf - headers[*num_headers].name) == 0) {
                *ret = -1;
                return NULL;
            }
            ++buf;
            for (;; ++buf) {
                CHECK_EOF();
                if (!(*buf == ' ' || *buf == '\t')) {
                    break;
                }
            }
        } else {
Exemplo n.º 5
0
static const char* parse_headers(const char* buf, const char* buf_end,
				 struct phr_header* headers,
				 size_t* num_headers, size_t max_headers,
				 int* ret)
{
  for (; ; ++*num_headers) {
    CHECK_EOF();
    if (*buf == '\015') {
      ++buf;
      EXPECT_CHAR('\012');
      break;
    } else if (*buf == '\012') {
      ++buf;
      break;
    }
    if (*num_headers == max_headers) {
      *ret = -1;
      return NULL;
    }
    if (*num_headers == 0 || ! (*buf == ' ' || *buf == '\t')) {
      /* parsing name, but do not discard SP before colon, see
       * http://www.mozilla.org/security/announce/2006/mfsa2006-33.html */
      headers[*num_headers].name = buf;
      for (; ; ++buf) {
	CHECK_EOF();
	if (*buf == ':') {
	  break;
	} else if (*buf < ' ') {
	  *ret = -1;
	  return NULL;
	}
      }
      headers[*num_headers].name_len = buf - headers[*num_headers].name;
      ++buf;
      for (; ; ++buf) {
	CHECK_EOF();
	if (! (*buf == ' ' || *buf == '\t')) {
	  break;
	}
      }
    } else {
      headers[*num_headers].name = NULL;
      headers[*num_headers].name_len = 0;
    }
    if ((buf = get_token_to_eol(buf, buf_end, &headers[*num_headers].value,
				&headers[*num_headers].value_len, ret))
	== NULL) {
      return NULL;
    }
  }
  return buf;
}
Exemplo n.º 6
0
const char* parse_request(const char* buf, const char* buf_end,
			  const char** method, size_t* method_len,
			  const char** path, size_t* path_len,
			  int* minor_version, struct phr_header* headers,
			  size_t* num_headers, size_t max_headers, int* ret)
{
  /* skip first empty line (some clients add CRLF after POST content) */
  CHECK_EOF();
  if (*buf == '\015') {
    ++buf;
    EXPECT_CHAR('\012');
  } else if (*buf == '\012') {
    ++buf;
  }
  
  /* parse request line */
  ADVANCE_TOKEN(*method, *method_len);
  ++buf;
  ADVANCE_TOKEN(*path, *path_len);
  ++buf;
  if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) {
    return NULL;
  }
  if (*buf == '\015') {
    ++buf;
    EXPECT_CHAR('\012');
  } else if (*buf == '\012') {
    ++buf;
  } else {
    *ret = -1;
    return NULL;
  }
  
  return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret);
}
Exemplo n.º 7
0
static const char* get_token_to_eol(const char* buf, const char* buf_end,
                                    const char** token, size_t* token_len,
                                    int* ret)
{
  const char* token_start = buf;
  
#ifdef __SSE4_2__
  static const char ranges1[] =
    "\0\010"
    /* allow HT */
    "\012\037"
    /* allow SP and up to but not including DEL */
    "\177\177"
    /* allow chars w. MSB set */
    ;
  int found;
  buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found);
  if (found)
    goto FOUND_CTL;
#else
  /* find non-printable char within the next 8 bytes, this is the hottest code; manually inlined */
  while (likely(buf_end - buf >= 8)) {
#define DOIT() if (unlikely(! IS_PRINTABLE_ASCII(*buf))) goto NonPrintable; ++buf
    DOIT(); DOIT(); DOIT(); DOIT();
    DOIT(); DOIT(); DOIT(); DOIT();
#undef DOIT
    continue;
  NonPrintable:
    if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) {
      goto FOUND_CTL;
    }
    ++buf;
  }
#endif
  for (; ; ++buf) {
    CHECK_EOF();
    if (unlikely(! IS_PRINTABLE_ASCII(*buf))) {
      if ((likely((unsigned char)*buf < '\040') && likely(*buf != '\011')) || unlikely(*buf == '\177')) {
        goto FOUND_CTL;
      }
    }
  }
 FOUND_CTL:
  if (likely(*buf == '\015')) {
    ++buf;
    EXPECT_CHAR('\012');
    *token_len = buf - 2 - token_start;
  } else if (*buf == '\012') {
    *token_len = buf - token_start;
    ++buf;
  } else {
    *ret = -1;
    return NULL;
  }
  *token = token_start;
  
  return buf;
}
Exemplo n.º 8
0
/* *_buf is always within [buf, buf_end) upon success */
static const char *parse_int(const char *buf, const char *buf_end, int *value, int *ret)
{
    int v;
    CHECK_EOF();
    if (!('0' <= *buf && *buf <= '9')) {
        *ret = -1;
        return NULL;
    }
    v = 0;
    for (;; ++buf) {
        CHECK_EOF();
        if ('0' <= *buf && *buf <= '9') {
            v = v * 10 + *buf - '0';
        } else {
            break;
        }
    }

    *value = v;
    return buf;
}
Exemplo n.º 9
0
static const char* get_token_to_eol(const char* buf, const char* buf_end,
				    const char** token, size_t* token_len,
				    int* ret)
{
  const char* token_start = buf;
  
  while (1) {
    if (likely(buf_end - buf >= 16)) {
      unsigned i;
      for (i = 0; i < 16; i++, ++buf) {
	if (unlikely((unsigned char)*buf <= '\015')
	    && (*buf == '\015' || *buf == '\012')) {
	  goto EOL_FOUND;
	}
      }
    } else {
      for (; ; ++buf) {
	CHECK_EOF();
	if (unlikely((unsigned char)*buf <= '\015')
	    && (*buf == '\015' || *buf == '\012')) {
	  goto EOL_FOUND;
	}
      }
    }
  }
 EOL_FOUND:
  if (*buf == '\015') {
    ++buf;
    EXPECT_CHAR('\012');
    *token_len = buf - 2 - token_start;
  } else { /* should be: *buf == '\012' */
    *token_len = buf - token_start;
    ++buf;
  }
  *token = token_start;
  
  return buf;
}
Exemplo n.º 10
0
static int scc_string_lexer(YYSTYPE *lvalp, YYLTYPE *llocp,scc_lex_t* lex) {
    unsigned pos;
    char c;

    for(pos = 0 ; 1 ; pos++) {
        c = scc_lex_at(lex,pos);
        CHECK_EOF(lex,c);
        if(c == '\\') { // skip escape
            pos++;
            continue;
        }
        if(c == '"' || c == '%') break;
    }
    
    // finished with a % escape
    if(c == '%') {
        scc_lex_push_lexer(lex,scc_string_var_lexer);
        // some string first ?
        if(pos > 0) {
            lvalp->str = scc_lex_gets(lex,pos);
            //scc_lex_getc(lex); // eat the %
            scc_unescape_string(lvalp->str);
            return STRING;
        }
        // directly switch to the string var lexer
        //scc_lex_getc(lex); // eat the %
        return 0;
    }

    
    lvalp->str = scc_lex_gets(lex,pos);
    scc_lex_getc(lex); // eat the closing "
    scc_unescape_string(lvalp->str);
    // switch back to the previous parser
    scc_lex_pop_lexer(lex);
    return STRING;    
}
Exemplo n.º 11
0
void TokenReader::nextToken(Token& t) {
    int c;
    if (pushedback) {
	pushedback = false;
	t = last;
	//cout << "popped " << t.toString() << "\n";
	return;
    }
    skipWhitespace();

    t.sval.clear();
    t.lineno = lineno;
    
    // skipWhitespace always sets pbc
    CHECK_EOF(c = pbc);

    pbc = -1;

    long long ival, divisor;
    t.type = TT_INVALID;
    if (c == '"') {
	CHECK_EOF(NEXTC); // skip quote char
	while (c != '"') {
	    if (c=='\\') {
		CHECK_EOF(NEXTC);
		switch (c) {
		case 'n':
		    c='\n';
		    break;
		case 't':
		    c='\t';
		    break;
		case 'b':
		    c='\b';
		    break;
		}
	    }
	    t.sval += c;
	    CHECK_EOF(NEXTC);
	}
	t.type = TT_STRING;
    } else if ((c >= '0' && c <= '9') || c == '-') {
	int radix = 10;
	bool flt=false;
	bool minus=false;
	divisor=1;
	

	if (c == '0') {	
	    t.sval += c;
	    NEXTC; // won't hurt...
	    if (c == 'x' || c == 'X') {
		t.sval += c;
		radix=16;
		NEXTC;
	    } else if (IS_WHITESPACE_EOF(c)) {
		t.ival = 0;
		t.dval = 0;
		t.type=TT_INTEGER;

		last = t;
		//cout << "read " << t.toString() << "\n";
		return;
	    }
	}
    
	if (c == '-') {
	    minus=true;
	    t.sval += c;
	    CHECK_EOF(NEXTC);
	}
	ival = 0;
	while (c >= '0' && c <= '9' || c == '.' || c == 'e' || (radix == 16 && ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')))) {
	    minus=false;
	    t.sval += c;
	    if (c == 'e' && (radix != 16)) {
		flt = true;
	    }
	    if (c == '.') {
		if (flt) {
		    break;
		}
		flt=true;
	    }
	    NEXTC;
	}
	pbc=c;
	if (minus) {
	    t.type = TT_SYMBOL;
	    t.sval = "-";
	} else if (flt) {
	    t.type = TT_FLOAT;
	    t.dval = strtod(t.sval.c_str(),NULL);
	    t.ival = (int)t.dval;
	} else {
	    t.type = TT_INTEGER;
	    t.ival = strtol(t.sval.c_str(),NULL,0);
	    t.dval = t.ival;
	}
	
    } else if (c=='_' || isalpha(c)) {
	do {
	    t.sval += c;
	    NEXTC;
	} while (c=='_' || isalnum(c));
	
	t.type = TT_SYMBOL;
    } else {
	t.type = TT_SYMBOL;
	t.sval = c;
    }
    //cout << "read " << t.toString() << "\n";
    last = t;
    return;
}
Exemplo n.º 12
0
int scc_main_lexer(YYSTYPE *lvalp, YYLTYPE *llocp,scc_lex_t* lex) {
    char c,d;
    char* str,*ppd;
    int tpos = 0,pos = 0;
    int define_line = -1, define_col = -1;
    scc_keyword_t* keyword;

    c = scc_lex_at(lex,0);

    // EOF
    if(!c) return 0;

    //scc_lex_get_line_column(lex,&llocp->first_line,&llocp->first_column);

    // a sym, a keyword or an integer
    if(SCC_ISALNUM(c) || c == '_') {
        // read the whole word
        do {
            tpos++;
            c = scc_lex_at(lex,tpos);
            if(!c) {
                if(lex->error) return 0;
                break;
            }
        } while(SCC_ISALNUM(c) || c == '_');
        // Get the string
        str = scc_lex_gets(lex,tpos);

        // Is it an integer ?
        if(SCC_ISDIGIT(str[0])) {
            char* end;
            lvalp->integer = strtol(str,&end,0);
            if(end[0] != '\0') {
                scc_lex_error(lex,"Failed to parse integer: '%s'",str);
                free(str);
                return 0;
            }
            free(str);
            return INTEGER;
        }

        // Is it a define ?
        if(scc_lex_is_define(lex,str)) {
            scc_lex_expand_define(lex,str);
            return -1;
        }

        // Is it a keyword ?
        if((keyword = scc_is_keyword(str,scc_keywords,
                                     sizeof(scc_keywords)/sizeof(scc_keyword_t)-1))) {
            free(str);
            if(keyword->val >= 0)
                lvalp->integer = keyword->val;
            return keyword->type;
        }
        // then it's symbol
        lvalp->str = str;
        return SYM;
    }

    scc_lex_getc(lex);

// && &= & || |= | ++ += + -- -= -
#define OP_OPEQ_OQDBL(op,eq_val,dbl_type,dbl_val)  \
        d = scc_lex_at(lex,0);                     \
        CHECK_EOF(lex,d);                          \
        if(d == op) {                              \
            scc_lex_getc(lex);                     \
            lvalp->integer = dbl_val;              \
            return dbl_type;                       \
        } else if(d == '=') {                      \
            scc_lex_getc(lex);                     \
            lvalp->integer = eq_val;               \
            return ASSIGN;                         \
        }                                          \
        lvalp->integer = op;                       \
        return op


// == = != ! >= > <= < *= *
#define OP_OPEQ(op,eq_type,eq_val)                 \
        d = scc_lex_at(lex,0);                     \
        CHECK_EOF(lex,d);                          \
        if(d == '=') {                             \
            scc_lex_getc(lex);                     \
            lvalp->integer = eq_val;               \
            return eq_type;                        \
        }                                          \
        lvalp->integer = op;                       \
        return op                                  \


    switch(c) {
        // && &= &
    case '&':
        OP_OPEQ_OQDBL('&',AAND,LAND,LAND);

        // || |= |
    case '|':
        OP_OPEQ_OQDBL('|',AOR,LOR,LOR);

        // ++ += +
    case '+':
        OP_OPEQ_OQDBL('+',AADD,SUFFIX,INC);

        // -- -= -
    case '-':
        OP_OPEQ_OQDBL('-',ASUB,SUFFIX,DEC);
        break;

    case '=':
        d = scc_lex_at(lex,0);
        CHECK_EOF(lex,d);
        if(d == '=') {
            scc_lex_getc(lex);
            lvalp->integer = EQ;
            return EQ;
        }
        lvalp->integer = '=';
        return ASSIGN;

        // != !
    case '!':
        OP_OPEQ('!',NEQ,NEQ);

        // >= >
    case '>':
        OP_OPEQ('>',GE,GE);

        // <= <
    case '<':
        OP_OPEQ('<',LE,LE);

        // *= *
    case '*':
        OP_OPEQ('*',ASSIGN,AADD);

        // /= // /* // /
    case '/':
        d = scc_lex_at(lex,0);
        if(d == '=') {  // divide and assign
            scc_lex_getc(lex);
            lvalp->integer = ADIV;
            return ASSIGN;
        } else if(d == '/') { // single line comments
            tpos = scc_lex_strchr(lex,1,'\n');
            if(tpos > 0)
                scc_lex_drop(lex,tpos+1);
            return -1;
        } else if(d == '*') { // multi line comments
            do {
                tpos = scc_lex_strchr(lex,tpos+1,'/');
                if(tpos < 0) {
                    // TODO warn instead
                    if(!lex->error)
                        scc_lex_error(lex,"Unfinished multi line comment");
                    return 0;
                }
            } while(scc_lex_at(lex,tpos-1) != '*');
            scc_lex_drop(lex,tpos+1);
            return -1;
        }
        // divide
        lvalp->integer = '/';
        return '/';

        // :: :
    case ':':
        d = scc_lex_at(lex,0);
        if(d == ':') {
            scc_lex_getc(lex);
            return NS;
        }
        lvalp->integer = ':';
        return ':';

        // ; , @ ( ) [ ] { } ? 
    case ';':
    case ',':
    case '@':
    case '(':
    case ')':
    case '[':
    case ']':
    case '{':
    case '}':
    case '?':
        lvalp->integer = c;
        return c;

        // single chars
    case '\'':
        c = scc_lex_getc(lex);
        if(c == '\\')
            c = scc_lex_getc(lex);
        CHECK_EOF(lex,c);
        d = scc_lex_getc(lex);
        CHECK_EOF(lex,d);
        if(d != '\'') {
            scc_lex_error(lex,"Unterminated character constant.");
            return 0;
        }
        lvalp->integer = c;
        return INTEGER;

        // strings
    case '"':
        scc_lex_push_lexer(lex,scc_string_lexer);
        return 0;

        // pre precessor
    case '#':
        // read the directive name
        c = scc_lex_at(lex,tpos);
        CHECK_EOF(lex,c);
        // skip initial spaces
        while(c == ' ' || c == '\t') {
            tpos++;
            c = scc_lex_at(lex,tpos);
            CHECK_EOF(lex,c);
        }
        // check that the first char is an alpha
        if(!SCC_ISALPHA(c)) {
            scc_lex_error(lex,"Invalid preprocessor directive.");
            return 0;
        }
        // drop the spaces
        scc_lex_drop(lex,tpos);
        // read the name
        tpos = 0;
        do {
            tpos++;
            c = scc_lex_at(lex,tpos);
            CHECK_EOF(lex,c);
        } while(SCC_ISALPHA(c));
        // check we ended on a space
        if(c != ' ' && c != '\t' && c != '\n') {
            scc_lex_error(lex,"Invalid preprocessor directive.");
            return 0;
        }
        // read the directive
        ppd = scc_lex_gets(lex,tpos);

        str = NULL;
        while(1) {
            // skip spaces
            tpos = 0;
            while(c == ' ' || c == '\t') {
                tpos++;
                c = scc_lex_at(lex,tpos);
                CHECK_EOF(lex,c);
            }
            // only space, that's it for now
            if(c == '\n') {
                scc_lex_drop(lex,tpos+1);
                 break;
            } else
                scc_lex_drop(lex,tpos);

            // Store the arg start position
            if(define_line < 0)
                scc_lex_get_line_column(lex,&define_line,&define_col);

            // find the eol
            tpos = scc_lex_strchr(lex,0,'\n');
            if(tpos < 0) { // we should do better here
                scc_lex_error(lex,"Unexpected eof");
                return 0;
            }
            // count the leading spaces
            pos = tpos;
            do {
                pos--;
                c = scc_lex_at(lex,pos);
                CHECK_EOF(lex,c);
            } while(c == ' ' || c == '\t');
            // not finished on a \, we are done
            if(c != '\\') {
                str = scc_lex_strcat(lex,str,pos+1);
                break;
            }
            // read that line
            str = scc_lex_strcat(lex,str,pos);
            // and drop the \ and the spaces
            scc_lex_drop(lex,tpos+1-pos);
        }

        // call the preproc
        tpos = scc_preproc_lexer(lex,ppd,str,define_line,define_col);
        free(ppd);
        if(str) free(str);
        return tpos;

    case ' ':
    case '\n':
    case '\t':
        do {
            c = scc_lex_at(lex,tpos);
            tpos++;
        } while (c == ' ' || c == '\n' || c == '\t');
        scc_lex_drop(lex,tpos-1);
        return -1;
            

    default:
        scc_lex_error(lex,"Unrecognized character: '%c'",c);
        return 0;
    }
    
}
Exemplo n.º 13
0
int phr_parse_request(const char* _buf, size_t len, const char** method,
		      size_t* method_len, const char** path, size_t* path_len,
		      int* minor_version, struct phr_header* headers,
		      size_t* num_headers, size_t last_len)
{
  const char * buf = _buf, * buf_end = buf + len;
  size_t max_headers;
  
  /* if last_len != 0, check if the request is complete (a fast countermeasure
     againt slowloris */
  if (last_len != 0) {
    int r = is_complete(buf, buf_end, last_len);
    if (r != 0) {
      return r;
    }
  }
  
  /* skip first empty line (some clients add CRLF after POST content) */
  CHECK_EOF();
  if (*buf == '\r') {
    ++buf;
    EXPECT('\n');
  } else if (*buf == '\n') {
    ++buf;
  }
  
  /* parse request line */
  *method = buf;
  ADVANCE_TOKEN();
  *method_len = buf - *method;
  ++buf;
  *path = buf;
  ADVANCE_TOKEN();
  *path_len = buf - *path;
  ++buf;
  EXPECT('H'); EXPECT('T'); EXPECT('T'); EXPECT('P'); EXPECT('/'); EXPECT('1');
  EXPECT('.');
  *minor_version = 0;
  for (; ; ++buf) {
    CHECK_EOF();
    if ('0' <= *buf && *buf <= '9') {
      *minor_version = *minor_version * 10 + *buf - '0';
    } else {
      break;
    }
  }
  if (*buf == '\r') {
    ++buf;
    EXPECT('\n');
  } else if (*buf == '\n') {
    ++buf;
  } else {
    return -1;
  }

  /* parse headers */
  max_headers = *num_headers;
  for (*num_headers = 0; ; ++*num_headers) {
    CHECK_EOF();
    if (*buf == '\r') {
      ++buf;
      EXPECT('\n');
      break;
    } else if (*buf == '\n') {
      ++buf;
      break;
    }
    if (*num_headers == max_headers) {
      return -1;
    }
    if (*num_headers == 0 || ! (*buf == ' ' || *buf == '\t')) {
      /* parsing name */
      headers[*num_headers].name = buf;
      for (; ; ++buf) {
	CHECK_EOF();
	if (*buf == ':') {
	  break;
	} else if (*buf < ' ') {
	  return -1;
	}
      }
      headers[*num_headers].name_len = buf - headers[*num_headers].name;
      ++buf;
      for (; ; ++buf) {
	CHECK_EOF();
	if (! (*buf == ' ' || *buf == '\t')) {
	  break;
	}
      }
    } else {
      headers[*num_headers].name = NULL;
      headers[*num_headers].name_len = 0;
    }
    headers[*num_headers].value = buf;
    for (; ; ++buf) {
      CHECK_EOF();
      if (*buf == '\r') {
	headers[*num_headers].value_len = buf - headers[*num_headers].value;
	++buf;
	EXPECT('\n');
	break;
      } else if (*buf == '\n') {
	headers[*num_headers].value_len = buf - headers[*num_headers].value;
	++buf;
	break;
      }
    }
  }
  
  return buf - _buf;
}
Exemplo n.º 14
0
static int scc_string_var_lexer(YYSTYPE *lvalp, YYLTYPE *llocp,scc_lex_t* lex) {
    char c,d;
    char* esc = "%ivVnsfc";
    int tpos = 0;
    scc_str_t* str;

    scc_lex_pop_lexer(lex);

    c = scc_lex_getc(lex); // eat the %
    CHECK_EOF(lex,c);

    c = scc_lex_at(lex,0); // get the command
    CHECK_EOF(lex,c);

    // check that it's a known escape
    if(!strchr(esc,c))
        return 0;
    else
        scc_lex_getc(lex); 

    if(c == '%') {
        lvalp->str = strdup("%");
        d = scc_lex_at(lex,0);
        // little hack to get rid of the usless empty string
        if(d == '"') {
            scc_lex_getc(lex);
            scc_lex_pop_lexer(lex);
        }
        return STRING;
    }

    d = scc_lex_at(lex,0);
    CHECK_EOF(lex,d);

    if(d != '{') return 0;
    // read the word
    do {
        tpos++;
        d = scc_lex_at(lex,tpos);
        if(!d) {
            if(lex->error) return 0;
            break;
        }
    } while(SCC_ISALNUM(d) || d == '_');
    
    if(d != '}') return 0;
    
    lvalp->strvar = str = calloc(1,sizeof(scc_str_t));
    // read out the string
    scc_lex_getc(lex); // {
    str->str = scc_lex_gets(lex,tpos-1);
    scc_lex_getc(lex); // }
    
    switch(c) {
    case 'i':
        str->type = SCC_STR_INT;
        break;
    case 'v':
        str->type = SCC_STR_VERB;
        break;
    case 'V':
        str->type = SCC_STR_VOICE;
        break;
    case 'n':
        str->type = SCC_STR_NAME;
        break;
    case 's':
        str->type = SCC_STR_STR;
        break;
    case 'f':
        str->type = SCC_STR_FONT;
        break;
    case 'c':  {
        char* end;
        int val  = strtol(str->str,&end,0);
        if(end[0] != '\0' || val < 0 || val > 255) {
            scc_lex_error(lex,"Invalid color number: %s\n",str->str);
            return 0;
        }
        str->type = SCC_STR_COLOR;
        str->str = realloc(str->str,2);
        SCC_SET_16LE(str->str,0,val);
    } break;
    }

    d = scc_lex_at(lex,0);
    if(d == '"') {
        scc_lex_getc(lex);
        scc_lex_pop_lexer(lex);
    }

    return STRVAR;
}
Exemplo n.º 15
0
Arquivo: file.c Projeto: ancuop/h2o
static size_t *process_range(h2o_mem_pool_t *pool, h2o_iovec_t *range_value, size_t file_size, size_t *ret)
{
#define CHECK_EOF()                                                                                                                \
    if (buf == buf_end)                                                                                                            \
        return NULL;

#define CHECK_OVERFLOW(range)                                                                                                      \
    if (range == SIZE_MAX)                                                                                                         \
        return NULL;

    size_t range_start = SIZE_MAX, range_count = 0;
    char *buf = range_value->base, *buf_end = buf + range_value->len;
    int needs_comma = 0;
    H2O_VECTOR(size_t) ranges = {};

    if (range_value->len < 6 || memcmp(buf, "bytes=", 6) != 0)
        return NULL;

    buf += 6;
    CHECK_EOF();

    /* most range requests contain only one range */
    do {
        while (1) {
            if (*buf != ',') {
                if (needs_comma)
                    return NULL;
                break;
            }
            needs_comma = 0;
            buf++;
            while (H2O_UNLIKELY(*buf == ' ') || H2O_UNLIKELY(*buf == '\t')) {
                buf++;
                CHECK_EOF();
            }
        }
        if (H2O_UNLIKELY(buf == buf_end))
            break;
        if (H2O_LIKELY((range_start = h2o_strtosizefwd(&buf, buf_end - buf)) != SIZE_MAX)) {
            CHECK_EOF();
            if (*buf++ != '-')
                return NULL;
            range_count = h2o_strtosizefwd(&buf, buf_end - buf);
            if (H2O_UNLIKELY(range_start >= file_size)) {
                range_start = SIZE_MAX;
            } else if (H2O_LIKELY(range_count != SIZE_MAX)) {
                if (H2O_UNLIKELY(range_count > file_size - 1))
                    range_count = file_size - 1;
                if (H2O_LIKELY(range_start <= range_count))
                    range_count -= range_start - 1;
                else
                    range_start = SIZE_MAX;
            } else {
                range_count = file_size - range_start;
            }
        } else if (H2O_LIKELY(*buf++ == '-')) {
            CHECK_EOF();
            range_count = h2o_strtosizefwd(&buf, buf_end - buf);
            if (H2O_UNLIKELY(range_count == SIZE_MAX))
                return NULL;
            if (H2O_LIKELY(range_count != 0)) {
                if (H2O_UNLIKELY(range_count > file_size))
                    range_count = file_size;
                range_start = file_size - range_count;
            } else {
                range_start = SIZE_MAX;
            }
        } else {
            return NULL;
        }

        if (H2O_LIKELY(range_start != SIZE_MAX)) {
            h2o_vector_reserve(pool, &ranges, ranges.size + 2);
            ranges.entries[ranges.size++] = range_start;
            ranges.entries[ranges.size++] = range_count;
        }
        if (buf != buf_end)
            while (H2O_UNLIKELY(*buf == ' ') || H2O_UNLIKELY(*buf == '\t')) {
                buf++;
                CHECK_EOF();
            }
        needs_comma = 1;
    } while (H2O_UNLIKELY(buf < buf_end));
    *ret = ranges.size / 2;
    return ranges.entries;
#undef CHECK_EOF
#undef CHECK_OVERFLOW
}
Exemplo n.º 16
0
Arquivo: util.c Projeto: nwcs/h2o
static ssize_t parse_proxy_line(char *src, size_t len, struct sockaddr *sa, socklen_t *salen)
{
#define CHECK_EOF()                                                                                                                \
    if (p == end)                                                                                                                  \
    return -2
#define EXPECT_CHAR(ch)                                                                                                            \
    do {                                                                                                                           \
        CHECK_EOF();                                                                                                               \
        if (*p++ != ch)                                                                                                            \
            return -1;                                                                                                             \
    } while (0)
#define SKIP_TO_WS()                                                                                                               \
    do {                                                                                                                           \
        do {                                                                                                                       \
            CHECK_EOF();                                                                                                           \
        } while (*p++ != ' ');                                                                                                     \
        --p;                                                                                                                       \
    } while (0)

    char *p = src, *end = p + len;
    void *addr;
    in_port_t *port;

    /* "PROXY "*/
    EXPECT_CHAR('P');
    EXPECT_CHAR('R');
    EXPECT_CHAR('O');
    EXPECT_CHAR('X');
    EXPECT_CHAR('Y');
    EXPECT_CHAR(' ');

    /* "TCP[46] " */
    CHECK_EOF();
    if (*p++ != 'T') {
        *salen = 0; /* indicate that no data has been obtained */
        goto SkipToEOL;
    }
    EXPECT_CHAR('C');
    EXPECT_CHAR('P');
    CHECK_EOF();
    switch (*p++) {
    case '4':
        *salen = sizeof(struct sockaddr_in);
        *((struct sockaddr_in *)sa) = (struct sockaddr_in){};
        sa->sa_family = AF_INET;
        addr = &((struct sockaddr_in *)sa)->sin_addr;
        port = &((struct sockaddr_in *)sa)->sin_port;
        break;
    case '6':
        *salen = sizeof(struct sockaddr_in6);
        *((struct sockaddr_in6 *)sa) = (struct sockaddr_in6){};
        sa->sa_family = AF_INET6;
        addr = &((struct sockaddr_in6 *)sa)->sin6_addr;
        port = &((struct sockaddr_in6 *)sa)->sin6_port;
        break;
    default:
        return -1;
    }
    EXPECT_CHAR(' ');

    /* parse peer address */
    char *addr_start = p;
    SKIP_TO_WS();
    *p = '\0';
    if (inet_pton(sa->sa_family, addr_start, addr) != 1)
        return -1;
    *p++ = ' ';

    /* skip local address */
    SKIP_TO_WS();
    ++p;

    /* parse peer port */
    char *port_start = p;
    SKIP_TO_WS();
    *p = '\0';
    unsigned short usval;
    if (sscanf(port_start, "%hu", &usval) != 1)
        return -1;
    *port = htons(usval);
    *p++ = ' ';

SkipToEOL:
    do {
        CHECK_EOF();
    } while (*p++ != '\r');
    CHECK_EOF();
    if (*p++ != '\n')
        return -2;
    return p - src;

#undef CHECK_EOF
#undef EXPECT_CHAR
#undef SKIP_TO_WS
}
Exemplo n.º 17
0
int 
airport::Uriparser::nu_parse_uri(const char* _buf, size_t len, const char** scheme, size_t *scheme_len, const char **host, size_t *host_len, int *port, const char **path_query, int*path_query_len, const char **fragment, int*fragment_len) {
    const char * buf = _buf, * buf_end = buf + len;

    *scheme = buf;
    for (;;++buf) {
        CHECK_EOF();
        if (':' == *buf) {
            break;
        }
    }
    *scheme_len = buf - *scheme;
    EXPECT(':'); EXPECT('/'); EXPECT('/');

    *host = buf;
    *port = 0;
    *host_len = 0;
    *path_query_len = 0;
    *fragment_len = 0;
    for (;;++buf) {
        if (buf == buf_end) {
            *host_len = buf - *host;
            return 0;
        }
        if (':' == *buf) { /* with port */
            *host_len = buf - *host;
            buf++;

            *port = 0;
            for (;'0' <= *buf && *buf <= '9';buf++) {
                if (buf == buf_end) {
                    return 0;
                }
                *port = *port * 10 + (*buf - '0');
            }
            if (buf == buf_end) {
                return 0;
            }
            break;
        }
        if ('/' == *buf) { /* no port */
            *host_len = buf - *host;
            break;
        }
    }
    if (*host_len==0)
    {
        buf = _buf;
    }
    *path_query = buf;
    *path_query_len = buf_end - buf;
    for (;;++buf) {
        if (buf == buf_end) {
            return 0;
        }
        if ('#' == *buf)
        {
            *path_query_len = buf - *path_query;
            buf ++;
            if (buf == buf_end) {
                return 0;
            }
            *fragment = buf;
            *fragment_len = buf_end - buf;
            break;
        }
    }
    return 0;
}