# HG changeset patch # User hucongcong <hucon...@foxmail.com> # Date 1476342771 -28800 # Thu Oct 13 15:12:51 2016 +0800 # Node ID 93bad8b82169245db6d4fe4e6b6c823221ee6a38 # Parent 7cdf69d012f02a80c94d930b29c71847e203e4d6 Http mp4: replace strtod() with improved ngx_atofp() because precision problem.
function prototype is ngx_atofp(u_char *line, size_t n, size_t point). use case based on the old version: ngx_atofp("12.2193", 7, 0) returns NGX_ERROR, ngx_atofp("12.2193", 7, 2) returns NGX_ERROR. now, allow point = 0 or point less than the number of fractional digits. ngx_atofp("12.2193", 7, 0) returns 12, ngx_atofp("12.2193", 7, 2) returns 1221. retained all the required or right feature at the same time, e.g., ngx_atofp("10.5", 4, 2) returns 1050. deprecated strtod() in ngx_http_mp4_module, since the precision problem, which was metioned in http://stackoverflow.com/questions/18361261, e.g., (int) (strtod((char *) "32.480", NULL) * 1000) returns 32479. another way to solve this problem is like this round(strtod()), e.g., (int) round((strtod((char *) "32.480", NULL) * 1000)) returns 32480, but its not necessary, since we have a better ngx_atofp(). diff -r 7cdf69d012f0 -r 93bad8b82169 src/core/ngx_string.c --- a/src/core/ngx_string.c Tue Oct 11 18:03:01 2016 +0300 +++ b/src/core/ngx_string.c Thu Oct 13 15:12:51 2016 +0800 @@ -945,8 +945,8 @@ for (value = 0; n--; line++) { - if (point == 0) { - return NGX_ERROR; + if (dot && point == 0) { + break; } if (*line == '.') { diff -r 7cdf69d012f0 -r 93bad8b82169 src/http/modules/ngx_http_mp4_module.c --- a/src/http/modules/ngx_http_mp4_module.c Tue Oct 11 18:03:01 2016 +0300 +++ b/src/http/modules/ngx_http_mp4_module.c Thu Oct 13 15:12:51 2016 +0800 @@ -535,28 +535,14 @@ if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) { - /* - * A Flash player may send start value with a lot of digits - * after dot so strtod() is used instead of atofp(). NaNs and - * infinities become negative numbers after (int) conversion. - */ - - ngx_set_errno(0); - start = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - start = -1; - } + /* start = -1 when NGX_ERROR returned by ngx_atofp */ + + start = ngx_atofp(value.data, value.len, 3); } if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) { - ngx_set_errno(0); - end = (int) (strtod((char *) value.data, NULL) * 1000); - - if (ngx_errno != 0) { - end = -1; - } + end = ngx_atofp(value.data, value.len, 3); if (end > 0) { if (start < 0) { _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel