[patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.
Maxim Dounin
mdounin at mdounin.ru
Tue Oct 18 18:25:52 UTC 2016
Hello!
On Thu, Oct 13, 2016 at 04:45:23PM +0800, 月耳 wrote:
> # HG changeset patch
> # User hucongcong <hucong.c at 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 == '.') {
With such a change it won't be possible to detect errors in other
places where ngx_atofp() is used. In particular, something like
split_clients $remote_addr $foo {
0.015% 1;
* 2;
}
will silently discard trailing 5. Moreover, even something like
split_clients $remote_addr $foo {
0.01foobar% 1;
* 2;
}
will be silently accepted.
[...]
--
Maxim Dounin
http://nginx.org/
More information about the nginx-devel
mailing list