/* is response */
if (pre_header == http) {
- char *status = NULL;
- const char *code = http + sizeof("HTTP/X.x");
+ const char *status = NULL, *code = http + sizeof("HTTP/X.x");
info->type = PHP_HTTP_RESPONSE;
while (' ' == *code) ++code;
if (code && end > code) {
- PHP_HTTP_INFO(info).response.code = strtol(code, &status, 10);
+ /* rfc7230#3.1.2 The status-code element is a 3-digit integer code */
+ PHP_HTTP_INFO(info).response.code = 100*(*code++ - '0');
+ PHP_HTTP_INFO(info).response.code += 10*(*code++ - '0');
+ PHP_HTTP_INFO(info).response.code += *code++ - '0';
+ if (PHP_HTTP_INFO(info).response.code < 100 || PHP_HTTP_INFO(info).response.code > 599) {
+ if (free_info) {
+ php_http_info_free(&info);
+ }
+ return NULL;
+ }
+ status = code;
} else {
PHP_HTTP_INFO(info).response.code = 0;
}
php_http_version_t *php_http_version_parse(php_http_version_t *v, const char *str TSRMLS_DC)
{
long major, minor;
- char separator = 0, *stop = NULL;
+ char separator = 0;
register const char *ptr = str;
switch (*ptr) {
++ptr;
/* no break */
default:
- major = strtol(ptr, &stop, 10);
- if (stop && stop != ptr && major != LONG_MIN && major != LONG_MAX) {
- separator = *stop;
+ /* rfc7230#2.6 The HTTP version number consists of two decimal digits separated by a "." (period or decimal point) */
+ major = *ptr++ - '0';
+ if (major >= 0 && major <= 9) {
+ separator = *ptr++;
if (separator) {
if (separator != '.' && separator != ',') {
- php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Non-standard version separator '%c' in HTTP protocol version '%s'", separator, ptr);
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Non-standard version separator '%c' in HTTP protocol version '%s'", separator, ptr - 2);
}
- ptr = stop + 1;
- minor = strtol(ptr, &stop, 10);
- if (minor != LONG_MIN && minor != LONG_MAX) {
+ minor = *ptr - '0';
+ if (minor >= 0 && minor <= 9) {
return php_http_version_init(v, major, minor TSRMLS_CC);
}
}