mirror of
https://github.com/nginx/nginx.git
synced 2025-06-12 21:52:41 +08:00
Mp4: introduced custom version of ngx_atofp().
This allows to correctly parse "start" and "end" arguments without null-termination (ticket #475), and also fixes rounding errors observed with strtod() when using i387 instructions.
This commit is contained in:
parent
9ea918a41d
commit
271d306056
@ -216,6 +216,7 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
static ngx_int_t ngx_http_mp4_handler(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_mp4_handler(ngx_http_request_t *r);
|
||||||
|
static ngx_int_t ngx_http_mp4_atofp(u_char *line, size_t n, size_t point);
|
||||||
|
|
||||||
static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4);
|
static ngx_int_t ngx_http_mp4_process(ngx_http_mp4_file_t *mp4);
|
||||||
static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
|
static ngx_int_t ngx_http_mp4_read_atom(ngx_http_mp4_file_t *mp4,
|
||||||
@ -537,26 +538,15 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* A Flash player may send start value with a lot of digits
|
* A Flash player may send start value with a lot of digits
|
||||||
* after dot so strtod() is used instead of atofp(). NaNs and
|
* after dot so a custom function is used instead of ngx_atofp().
|
||||||
* infinities become negative numbers after (int) conversion.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ngx_set_errno(0);
|
start = ngx_http_mp4_atofp(value.data, value.len, 3);
|
||||||
start = (int) (strtod((char *) value.data, NULL) * 1000);
|
|
||||||
|
|
||||||
if (ngx_errno != 0) {
|
|
||||||
start = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) {
|
if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) {
|
||||||
|
|
||||||
ngx_set_errno(0);
|
end = ngx_http_mp4_atofp(value.data, value.len, 3);
|
||||||
end = (int) (strtod((char *) value.data, NULL) * 1000);
|
|
||||||
|
|
||||||
if (ngx_errno != 0) {
|
|
||||||
end = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (end > 0) {
|
if (end > 0) {
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
@ -686,6 +676,62 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_mp4_atofp(u_char *line, size_t n, size_t point)
|
||||||
|
{
|
||||||
|
ngx_int_t value, cutoff, cutlim;
|
||||||
|
ngx_uint_t dot;
|
||||||
|
|
||||||
|
/* same as ngx_atofp(), but allows additional digits */
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cutoff = NGX_MAX_INT_T_VALUE / 10;
|
||||||
|
cutlim = NGX_MAX_INT_T_VALUE % 10;
|
||||||
|
|
||||||
|
dot = 0;
|
||||||
|
|
||||||
|
for (value = 0; n--; line++) {
|
||||||
|
|
||||||
|
if (*line == '.') {
|
||||||
|
if (dot) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
dot = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*line < '0' || *line > '9') {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (point == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = value * 10 + (*line - '0');
|
||||||
|
point -= dot;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (point--) {
|
||||||
|
if (value > cutoff) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = value * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
|
ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user