Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-26 Thread Maxim Dounin
Hello!

On Thu, Oct 27, 2016 at 12:40:21AM +0800, 胡聪 (hucc) wrote:

> Hello!
> 
> On Wed, Oct 26, 2016 at 8:31PM, Maxim Dounin wrote:
> 
> >On Wed, Oct 26, 2016 at 05:10:25PM +0800, 胡聪 (hucc) wrote:
> > 
> >> VOD (video on demand) module which support requesting time range
> >> also need the special function, so i would like to see that nginx-devel
> >> add a function in Core, that would be helpful. Possible patch below.
> >
> >If you mean https://github.com/kaltura/nginx-vod-module, then I 
> >don't think it does.  Quick look suggests that it uses 
> >milliseconds to specify times instead, and uses ngx_atoi() to 
> >parse them.  It doesn't use strtod() at all, and the only place it 
> >uses ngx_atofp() now is to parse rate, and I don't think there are 
> >reasons to allow arbitrary numbers like in the mp4 case.
> >
> >The main problem with mp4 was that there were existing Flash 
> >clients nginx has to be compatible with, and some of them used to 
> >send incorrect start time specifications.  It is highly unlikely 
> >that the same unique situation affects other modules.
> 
> I don`t know how to make a more specific description because of my
> poor english.  What i mean about VOD is video-processing module in
> CDN provider, this scenario usually be asked to provide parameter
> parsing which support seconds and milliseconds.  I am developing a
> series of moudles which are a bit like nginx-vod-module and new
> function will be used based on my experience.  I just think the usage
> of atofp() is very limited, maybe a function supporting optional mode
> should be provided.  Anyway, the point is whether other modules
> need new function, i pointed out the scene i familiar with and hope
> this helps.

There is no problem with parsing seconds and milliseconds using 
ngx_atofp().  The problem with ngx_atofp() only appears if you 
have to support existing clients who already use invalid syntax.  
Unless you have to support such clients - you'd better use generic 
ngx_atofp() and reject attempts to use invalid syntax in the 
arguments.

-- 
Maxim Dounin
http://nginx.org/

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-26 Thread ???? (hucc)
Hello!

On Wed, Oct 26, 2016 at 8:31PM, Maxim Dounin wrote:

>On Wed, Oct 26, 2016 at 05:10:25PM +0800,  (hucc) wrote:
> 
>> VOD (video on demand) module which support requesting time range
>> also need the special function, so i would like to see that nginx-devel
>> add a function in Core, that would be helpful. Possible patch below.
>
>If you mean https://github.com/kaltura/nginx-vod-module, then I 
>don't think it does.  Quick look suggests that it uses 
>milliseconds to specify times instead, and uses ngx_atoi() to 
>parse them.  It doesn't use strtod() at all, and the only place it 
>uses ngx_atofp() now is to parse rate, and I don't think there are 
>reasons to allow arbitrary numbers like in the mp4 case.
>
>The main problem with mp4 was that there were existing Flash 
>clients nginx has to be compatible with, and some of them used to 
>send incorrect start time specifications.  It is highly unlikely 
>that the same unique situation affects other modules.

I don`t know how to make a more specific description because of my
poor english.  What i mean about VOD is video-processing module in
CDN provider, this scenario usually be asked to provide parameter
parsing which support seconds and milliseconds.  I am developing a
series of moudles which are a bit like nginx-vod-module and new
function will be used based on my experience.  I just think the usage
of atofp() is very limited, maybe a function supporting optional mode
should be provided.  Anyway, the point is whether other modules
need new function, i pointed out the scene i familiar with and hope
this helps.


Regards,
-hucc___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-26 Thread Maxim Dounin
Hello!

On Wed, Oct 26, 2016 at 05:10:25PM +0800, 胡聪 (hucc) wrote:

> On Wed, Oct 26, 2016 3:34 AM, Maxim Dounin wrote:
> 
> >Using strtod() should be avoided as it has other problems, see 
> >https://trac.nginx.org/nginx/ticket/475.  That is, an additional 
> >variant of ngx_atofp() is a way to go.
> >
> >
> >Last time we've looked into this, we've stumbled upon selecting a 
> >proper name for the additional function.  Looking into this again 
> >I tend to think that proper solution would be to use a special 
> >function withing the ngx_http_mp4_module itself.  Patch below.
> 
> 
> VOD (video on demand) module which support requesting time range
> also need the special function, so i would like to see that nginx-devel
> add a function in Core, that would be helpful. Possible patch below.

If you mean https://github.com/kaltura/nginx-vod-module, then I 
don't think it does.  Quick look suggests that it uses 
milliseconds to specify times instead, and uses ngx_atoi() to 
parse them.  It doesn't use strtod() at all, and the only place it 
uses ngx_atofp() now is to parse rate, and I don't think there are 
reasons to allow arbitrary numbers like in the mp4 case.

The main problem with mp4 was that there were existing Flash 
clients nginx has to be compatible with, and some of them used to 
send incorrect start time specifications.  It is highly unlikely 
that the same unique situation affects other modules.

-- 
Maxim Dounin
http://nginx.org/

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-26 Thread ???? (hucc)
Hello!


On Wed, Oct 26, 2016 3:34 AM, Maxim Dounin wrote:

>Using strtod() should be avoided as it has other problems, see 
>https://trac.nginx.org/nginx/ticket/475.  That is, an additional 
>variant of ngx_atofp() is a way to go.
>
>
>Last time we've looked into this, we've stumbled upon selecting a 
>proper name for the additional function.  Looking into this again 
>I tend to think that proper solution would be to use a special 
>function withing the ngx_http_mp4_module itself.  Patch below.


Sorry, my mistake, last patch lost some codes when i transfer codes
from Git to Mercurial.


VOD (video on demand) module which support requesting time range
also need the special function, so i would like to see that nginx-devel
add a function in Core, that would be helpful. Possible patch below.


 
# HG changeset patch

# User hucongcong 

# Date 1477473854 -28800

#  Wed Oct 26 17:24:14 2016 +0800

# Node ID 652843788cb08c18dcbc6bab2857a228093767e4

# Parent  56d6bfe6b609c565a9f500bde573fd9b488ff960

Core: add ngx_atosp().




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.




diff -r 56d6bfe6b609 -r 652843788cb0 src/core/ngx_string.c

--- a/src/core/ngx_string.c Fri Oct 21 16:28:39 2016 +0300

+++ b/src/core/ngx_string.c Wed Oct 26 17:24:14 2016 +0800

@@ -926,7 +926,9 @@

 }

 

 

-/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */

+/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050.

+ * can be replaced by ngx_atosp(line, n, point, 1).

+ */

 

 ngx_int_t

 ngx_atofp(u_char *line, size_t n, size_t point)

@@ -982,6 +984,76 @@

 }

 

 

+/* parse a fixed point number and do bounds check when strict is true, e.g.,

+ * ngx_atosp("12.2193", 3, 0, 0) returns 12,

+ * ngx_atosp("12.2193", 3, 0, 1) returns NGX_ERROR,

+ * ngx_atosp("12.2193", 6, 3, 1) returns 12219,

+ * ngx_atosp("12.2193", 7, 3, 1) returns NGX_ERROR,

+ * ngx_atosp("12.2193", 7, 3, 0) returns 12219.

+ */

+

+ngx_int_t

+ngx_atosp(u_char *line, size_t n, size_t point, unsigned strict)

+{

+ngx_int_t   value, cutoff, cutlim;

+ngx_uint_t  dot;

+

+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;

+}

+

+if (strict && point == 0) {

+return NGX_ERROR;

+}

+

+dot = 1;

+continue;

+}

+

+if (*line < '0' || *line > '9') {

+return NGX_ERROR;

+}

+

+if (dot && point == 0) {

+if (strict) {

+return NGX_ERROR;

+}

+

+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;

+}

+

+

 ssize_t

 ngx_atosz(u_char *line, size_t n)

 {

diff -r 56d6bfe6b609 -r 652843788cb0 src/core/ngx_string.h

--- a/src/core/ngx_string.h Fri Oct 21 16:28:39 2016 +0300

+++ b/src/core/ngx_string.h Wed Oct 26 17:24:14 2016 +0800

@@ -171,6 +171,7 @@

 

 ngx_int_t ngx_atoi(u_char *line, size_t n);

 ngx_int_t ngx_atofp(u_char *line, size_t n, size_t point);

+ngx_int_t ngx_atosp(u_char *line, size_t n, size_t point, unsigned strict);

 ssize_t ngx_atosz(u_char *line, size_t n);

 off_t ngx_atoof(u_char *line, size_t n);

 time_t ngx_atotm(u_char *line, size_t n);

diff -r 56d6bfe6b609 -r 652843788cb0 src/http/modules/ngx_http_mp4_module.c

--- a/src/http/modules/ngx_http_mp4_module.cFri Oct 21 16:28:39 2016 +0300

+++ b/src/http/modules/ngx_http_mp4_module.cWed Oct 26 17:24:14 2016 +0800

@@ -537,26 +537,15 @@

 

 /*

  * 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.

+ * after dot so ngx_atosp() is used instead of ngx_atofp().

  */

 

-ngx_set_errno(0);

-start = (int) (strtod((char *) value.data, NULL) * 1000);

-

-if (ngx_errno != 0) {

-start = -1;

-}

+start = ngx_atosp(value.data, value.len, 3, 0);

 }

 

 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 

Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-26 Thread ???? (hucc)
Hello!


On Wed, Oct 26, 2016 3:34 AM, Maxim Dounin wrote:

>Using strtod() should be avoided as it has other problems, see 
>https://trac.nginx.org/nginx/ticket/475.  That is, an additional 
>variant of ngx_atofp() is a way to go.
>
>
>Last time we've looked into this, we've stumbled upon selecting a 
>proper name for the additional function.  Looking into this again 
>I tend to think that proper solution would be to use a special 
>function withing the ngx_http_mp4_module itself.  Patch below.


VOD (video on demand) module which support requesting time range
also need the special function, so i would like to see that nginx-devel
add a function in Core, that would be helpful. Possible patch below.


 
# HG changeset patch

# User hucongcong 

# Date 1477468236 -28800

#  Wed Oct 26 15:50:36 2016 +0800

# Node ID 6376b8da3689011dfc8805381970f9ea2251c0a6

# Parent  56d6bfe6b609c565a9f500bde573fd9b488ff960

Core: add ngx_atosp().




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.




diff -r 56d6bfe6b609 -r 6376b8da3689 src/core/ngx_string.c

--- a/src/core/ngx_string.c Fri Oct 21 16:28:39 2016 +0300

+++ b/src/core/ngx_string.c Wed Oct 26 15:50:36 2016 +0800

@@ -926,7 +926,9 @@

 }

 

 

-/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */

+/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050.

+ * can be replaced by ngx_atosp(line, n, point, 1).

+ */

 

 ngx_int_t

 ngx_atofp(u_char *line, size_t n, size_t point)

@@ -982,6 +984,76 @@

 }

 

 

+/* parse a fixed point number and do bounds check when strict is true, e.g.,

+ * ngx_atosp("12.2193", 3, 0, 0) returns 12,

+ * ngx_atosp("12.2193", 3, 0, 1) returns NGX_ERROR,

+ * ngx_atosp("12.2193", 6, 3, 1) returns 12219,

+ * ngx_atosp("12.2193", 7, 3, 1) returns NGX_ERROR,

+ * ngx_atosp("12.2193", 7, 3, 0) returns 12219.

+ */

+

+ngx_int_t

+ngx_atosp(u_char *line, size_t n, size_t point, unsigned strict)

+{

+ngx_int_t   value, cutoff, cutlim;

+ngx_uint_t  dot;

+

+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;

+}

+

+if (strict && point == 0) {

+return NGX_ERROR;

+}

+

+dot = 1;

+continue;

+}

+

+if (*line < '0' || *line > '9') {

+return NGX_ERROR;

+}

+

+if (dot && point == 0) {

+if (strict) {

+return NGX_ERROR;

+}

+

+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;

+}

+

+

 ssize_t

 ngx_atosz(u_char *line, size_t n)

 {

diff -r 56d6bfe6b609 -r 6376b8da3689 src/http/modules/ngx_http_mp4_module.c

--- a/src/http/modules/ngx_http_mp4_module.cFri Oct 21 16:28:39 2016 +0300

+++ b/src/http/modules/ngx_http_mp4_module.cWed Oct 26 15:50:36 2016 +0800

@@ -537,26 +537,15 @@

 

 /*

  * 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.

+ * after dot so ngx_atosp() is used instead of ngx_atofp().

  */

 

-ngx_set_errno(0);

-start = (int) (strtod((char *) value.data, NULL) * 1000);

-

-if (ngx_errno != 0) {

-start = -1;

-}

+start = ngx_atosp(value.data, value.len, 3, 0);

 }

 

 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_atosp(value.data, value.len, 3, 0);

 

 if (end > 0) {

 if (start < 0) {___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-25 Thread Maxim Dounin
Hello!

On Wed, Oct 19, 2016 at 02:43:24PM +0800, 胡聪 (hucc) wrote:

> Hello!
> 
> 
> Thanks for reminding me! Illegal character should be checked
> also error detection in configration parser is needed.
> 
> 
> Considering that ngx_atofp() was used in some 3rd party modules,
> Would nginx-devel accept a new function like ngx_ato??() or
> lround(strtod()), or just let strtod() alone?

Using strtod() should be avoided as it has other problems, see 
https://trac.nginx.org/nginx/ticket/475.  That is, an additional 
variant of ngx_atofp() is a way to go.

Last time we've looked into this, we've stumbled upon selecting a 
proper name for the additional function.  Looking into this again 
I tend to think that proper solution would be to use a special 
function withing the ngx_http_mp4_module itself.  Patch below.

# HG changeset patch
# User Maxim Dounin 
# Date 1477416871 -10800
#  Tue Oct 25 20:34:31 2016 +0300
# Node ID 16dae7d3b770c63dc16ac06312a66c1bafc3308f
# Parent  56d6bfe6b609c565a9f500bde573fd9b488ff960
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.

diff --git a/src/http/modules/ngx_http_mp4_module.c 
b/src/http/modules/ngx_http_mp4_module.c
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -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_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_read_atom(ngx_http_mp4_file_t *mp4,
@@ -537,26 +538,15 @@ ngx_http_mp4_handler(ngx_http_request_t 
 
 /*
  * 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.
+ * after dot so a custom function is used instead of ngx_atofp().
  */
 
-ngx_set_errno(0);
-start = (int) (strtod((char *) value.data, NULL) * 1000);
-
-if (ngx_errno != 0) {
-start = -1;
-}
+start = ngx_http_mp4_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_http_mp4_atofp(value.data, value.len, 3);
 
 if (end > 0) {
 if (start < 0) {
@@ -687,6 +677,62 @@ ngx_http_mp4_handler(ngx_http_request_t 
 
 
 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 (point == 0) {
+break;
+}
+
+if (*line == '.') {
+if (dot) {
+return NGX_ERROR;
+}
+
+dot = 1;
+continue;
+}
+
+if (*line < '0' || *line > '9') {
+return NGX_ERROR;
+}
+
+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
 ngx_http_mp4_process(ngx_http_mp4_file_t *mp4)
 {
 off_t  start_offset, end_offset, adjustment;

-- 
Maxim Dounin
http://nginx.org/

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-18 Thread ???? (hucc)
Hello!


Thanks for reminding me! Illegal character should be checked
also error detection in configration parser is needed.


Considering that ngx_atofp() was used in some 3rd party modules,
Would nginx-devel accept a new function like ngx_ato??() or
lround(strtod()), or just let strtod() alone?


#lround(strtod())
 
--- a/src/http/modules/ngx_http_mp4_module.c
 
+++ b/src/http/modules/ngx_http_mp4_module.c
 
@@ -542,7 +542,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
 
  */
 
 
 
 ngx_set_errno(0);
 
-start = (int) (strtod((char *) value.data, NULL) * 1000);
 
+start = (int) (lround(strtod((char *) value.data, NULL) * 1000));
 
 
 
 if (ngx_errno != 0) {
 
 start = -1;
 
@@ -552,7 +552,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
 
 if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) {
 
 
 
 ngx_set_errno(0);
 
-end = (int) (strtod((char *) value.data, NULL) * 1000);
 
+end = (int) (lround(strtod((char *) value.data, NULL) * 1000));



#new function
 
+ngx_int_t
 
+ngx_atopi(u_char *line, size_t n, size_t point)
 
+{
 
+ngx_int_t   value, cutoff, cutlim;
 
+ngx_uint_t  dot;
 
+
 
+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 (dot && 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;
 
+}

-- Original --
From:  "Maxim Dounin";;
Send time: Wednesday, Oct 19, 2016 2:25 AM
To: "nginx-devel"; 

Subject:  Re: [patch][bugfix]Http mp4: replace strtod() with improved 
ngx_atofp() because precision problem.



Hello!

On Thu, Oct 13, 2016 at 04:45:23PM +0800,  wrote:

> # HG changeset patch
> # User hucongcong 
> # 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/

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Re: [patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-18 Thread Maxim Dounin
Hello!

On Thu, Oct 13, 2016 at 04:45:23PM +0800, 月耳 wrote:

> # HG changeset patch
> # User hucongcong 
> # 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/

___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

[patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-17 Thread ???? (hucc)
Hi, all
I've sent a patch.
http://mailman.nginx.org/pipermail/nginx-devel/2016-October/008932.html
that solves precision problem of ngx_http_mp4_module. 
Did any one noticed this patch.


Downstream cache system receives duplicate data by sending start&end parameters 
which are analyzed from moov box and aligned with the GOP. PotPlayer becomes 
not fluent when playing hls stream which is converted from the mp4 (duplicate 
data). Nginx can not quietly change the parameter value, and send non-requested 
data to clients or player. 


So the patch is helpful.


Regards,
-hucc___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel

[patch][bugfix]Http mp4: replace strtod() with improved ngx_atofp() because precision problem.

2016-10-13 Thread ????
# HG changeset patch
# User hucongcong 
# 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.cTue Oct 11 18:03:01 2016 +0300
+++ b/src/http/modules/ngx_http_mp4_module.cThu 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