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




<style type="text/css">p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #5230e1; background-color: #ffffff}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000; background-color: #ffffff}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000; background-color: #ffffff; min-height: 15.0px}
p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #34bc26; background-color: #ffffff}
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #cd7923; background-color: #ffffff}
p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #d53bd3; background-color: #ffffff}
p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #33bbc8; background-color: #ffffff}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style>


<p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"># HG changeset patch</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"># User hucongcong <hucong.c@foxmail.com></span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"># Date 1477473854 -28800</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">#      Wed Oct 26 17:24:14 2016 +0800</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"># Node ID 652843788cb08c18dcbc6bab2857a228093767e4</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"># Parent  56d6bfe6b609c565a9f500bde573fd9b488ff960</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">Core: add ngx_atosp().</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"><br></span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">This allows to correctly parse "start" and "end" arguments without</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">null-termination (ticket #475), and also fixes rounding errors observed</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">with strtod() when using i387 instructions.</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"><br></span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">diff -r 56d6bfe6b609 -r 652843788cb0 src/core/ngx_string.c</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">--- a/src/core/ngx_string.c<span class="Apple-tab-span" style="white-space:pre">  </span>Fri Oct 21 16:28:39 2016 +0300</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+++ b/src/core/ngx_string.c<span class="Apple-tab-span" style="white-space:pre">   </span>Wed Oct 26 17:24:14 2016 +0800</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">@@ -926,7 +926,9 @@</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+/* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050.</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ * can be replaced by ngx_atosp(line, n, point, 1).</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ */</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> ngx_int_t</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> ngx_atofp(u_char *line, size_t n, size_t point)</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">@@ -982,6 +984,76 @@</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+/* parse a fixed point number and do bounds check when strict is true, e.g.,</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ * ngx_atosp("12.2193", 3, 0, 0) returns 12,</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ * ngx_atosp("12.2193", 3, 0, 1) returns NGX_ERROR,</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ * ngx_atosp("12.2193", 6, 3, 1) returns 12219,</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ * ngx_atosp("12.2193", 7, 3, 1) returns NGX_ERROR,</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ * ngx_atosp("12.2193", 7, 3, 0) returns 12219.</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ */</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ngx_int_t</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ngx_atosp(u_char *line, size_t n, size_t point, unsigned strict)</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+{</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    ngx_int_t   value, cutoff, cutlim;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    ngx_uint_t  dot;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    if (n == 0) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        return NGX_ERROR;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    cutoff = NGX_MAX_INT_T_VALUE / 10;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    cutlim = NGX_MAX_INT_T_VALUE % 10;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    dot = 0;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    for (value = 0; n--; line++) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        if (*line == '.') {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            if (dot) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+                return NGX_ERROR;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            if (strict && point == 0) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+                return NGX_ERROR;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            dot = 1;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            continue;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        if (*line < '0' || *line > '9') {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            return NGX_ERROR;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        if (dot && point == 0) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            if (strict) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+                return NGX_ERROR;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            continue;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            return NGX_ERROR;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        value = value * 10 + (*line - '0');</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        point -= dot;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    while (point--) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        if (value > cutoff) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            return NGX_ERROR;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+        value = value * 10;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+    return value;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+}</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> ssize_t</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> ngx_atosz(u_char *line, size_t n)</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">diff -r 56d6bfe6b609 -r 652843788cb0 src/core/ngx_string.h</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">--- a/src/core/ngx_string.h<span class="Apple-tab-span" style="white-space:pre">  </span>Fri Oct 21 16:28:39 2016 +0300</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+++ b/src/core/ngx_string.h<span class="Apple-tab-span" style="white-space:pre">   </span>Wed Oct 26 17:24:14 2016 +0800</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">@@ -171,6 +171,7 @@</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> ngx_int_t ngx_atoi(u_char *line, size_t n);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> ngx_int_t ngx_atofp(u_char *line, size_t n, size_t point);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+ngx_int_t ngx_atosp(u_char *line, size_t n, size_t point, unsigned strict);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> ssize_t ngx_atosz(u_char *line, size_t n);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> off_t ngx_atoof(u_char *line, size_t n);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> time_t ngx_atotm(u_char *line, size_t n);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">diff -r 56d6bfe6b609 -r 652843788cb0 src/http/modules/ngx_http_mp4_module.c</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">--- a/src/http/modules/ngx_http_mp4_module.c<span class="Apple-tab-span" style="white-space:pre">    </span>Fri Oct 21 16:28:39 2016 +0300</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+++ b/src/http/modules/ngx_http_mp4_module.c<span class="Apple-tab-span" style="white-space:pre">  </span>Wed Oct 26 17:24:14 2016 +0800</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">@@ -537,26 +537,15 @@</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">             /*</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">              * A Flash player may send start value with a lot of digits</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-             * after dot so strtod() is used instead of atofp().  NaNs and</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-             * infinities become negative numbers after (int) conversion.</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+             * after dot so ngx_atosp() is used instead of ngx_atofp().</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">              */</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-            ngx_set_errno(0);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-            start = (int) (strtod((char *) value.data, NULL) * 1000);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-            if (ngx_errno != 0) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-                start = -1;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-            }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            start = ngx_atosp(value.data, value.len, 3, 0);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">         }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">         if (ngx_http_arg(r, (u_char *) "end", 3, &value) == NGX_OK) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-            ngx_set_errno(0);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-            end = (int) (strtod((char *) value.data, NULL) * 1000);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-            if (ngx_errno != 0) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-                end = -1;</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">-            }</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">+            end = ngx_atosp(value.data, value.len, 3, 0);</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;"> </span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">             if (end > 0) {</span></p><p class="p1"><span style="font-variant-ligatures: no-common-ligatures;">                 if (start < 0) {</span></p></div><div><br></div><style type="text/css">p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #33bbc8; background-color: #ffffff}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style><style type="text/css">p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #33bbc8; background-color: #ffffff}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000; background-color: #ffffff}
p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #34bc26; background-color: #ffffff}
p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #cd7923; background-color: #ffffff}
p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000; background-color: #ffffff; min-height: 15.0px}
p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #d53bd3; background-color: #ffffff}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style><style type="text/css">p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000; background-color: #ffffff; min-height: 15.0px}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000; background-color: #ffffff}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style>