bpo-36262: Fix _Py_dg_strtod() memory leak (goto undfl) (GH-12276) (G… · python/cpython@b140578
@@ -1514,8 +1514,9 @@ _Py_dg_strtod(const char *s00, char **se)
15141514ULong y, z, abs_exp;
15151515Long L;
15161516BCinfo bc;
1517-Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
1517+Bigint *bb = NULL, *bd = NULL, *bd0 = NULL, *bs = NULL, *delta = NULL;
15181518size_t ndigits, fraclen;
1519+double result;
1519152015201521dval(&rv) = 0.;
15211522@@ -1707,7 +1708,6 @@ _Py_dg_strtod(const char *s00, char **se)
17071708if (k > 9) {
17081709dval(&rv) = tens[k - 9] * dval(&rv) + z;
17091710 }
1710-bd0 = 0;
17111711if (nd <= DBL_DIG
17121712&& Flt_Rounds == 1
17131713 ) {
@@ -1877,14 +1877,11 @@ _Py_dg_strtod(const char *s00, char **se)
1877187718781878bd = Balloc(bd0->k);
18791879if (bd == NULL) {
1880-Bfree(bd0);
18811880 goto failed_malloc;
18821881 }
18831882Bcopy(bd, bd0);
18841883bb = sd2b(&rv, bc.scale, &bbe); /* srv = bb * 2^bbe */
18851884if (bb == NULL) {
1886-Bfree(bd);
1887-Bfree(bd0);
18881885 goto failed_malloc;
18891886 }
18901887/* Record whether lsb of bb is odd, in case we need this
@@ -1894,9 +1891,6 @@ _Py_dg_strtod(const char *s00, char **se)
18941891/* tdv = bd * 10**e; srv = bb * 2**bbe */
18951892bs = i2b(1);
18961893if (bs == NULL) {
1897-Bfree(bb);
1898-Bfree(bd);
1899-Bfree(bd0);
19001894 goto failed_malloc;
19011895 }
19021896@@ -1945,56 +1939,39 @@ _Py_dg_strtod(const char *s00, char **se)
1945193919461940/* Scale bb, bd, bs by the appropriate powers of 2 and 5. */
19471941if (bb5 > 0) {
1942+Bigint *bb1;
19481943bs = pow5mult(bs, bb5);
19491944if (bs == NULL) {
1950-Bfree(bb);
1951-Bfree(bd);
1952-Bfree(bd0);
19531945 goto failed_malloc;
19541946 }
19551947bb1 = mult(bs, bb);
19561948Bfree(bb);
19571949bb = bb1;
19581950if (bb == NULL) {
1959-Bfree(bs);
1960-Bfree(bd);
1961-Bfree(bd0);
19621951 goto failed_malloc;
19631952 }
19641953 }
19651954if (bb2 > 0) {
19661955bb = lshift(bb, bb2);
19671956if (bb == NULL) {
1968-Bfree(bs);
1969-Bfree(bd);
1970-Bfree(bd0);
19711957 goto failed_malloc;
19721958 }
19731959 }
19741960if (bd5 > 0) {
19751961bd = pow5mult(bd, bd5);
19761962if (bd == NULL) {
1977-Bfree(bb);
1978-Bfree(bs);
1979-Bfree(bd0);
19801963 goto failed_malloc;
19811964 }
19821965 }
19831966if (bd2 > 0) {
19841967bd = lshift(bd, bd2);
19851968if (bd == NULL) {
1986-Bfree(bb);
1987-Bfree(bs);
1988-Bfree(bd0);
19891969 goto failed_malloc;
19901970 }
19911971 }
19921972if (bs2 > 0) {
19931973bs = lshift(bs, bs2);
19941974if (bs == NULL) {
1995-Bfree(bb);
1996-Bfree(bd);
1997-Bfree(bd0);
19981975 goto failed_malloc;
19991976 }
20001977 }
@@ -2005,10 +1982,6 @@ _Py_dg_strtod(const char *s00, char **se)
2005198220061983delta = diff(bb, bd);
20071984if (delta == NULL) {
2008-Bfree(bb);
2009-Bfree(bs);
2010-Bfree(bd);
2011-Bfree(bd0);
20121985 goto failed_malloc;
20131986 }
20141987dsign = delta->sign;
@@ -2062,10 +2035,6 @@ _Py_dg_strtod(const char *s00, char **se)
20622035 }
20632036delta = lshift(delta,Log2P);
20642037if (delta == NULL) {
2065-Bfree(bb);
2066-Bfree(bs);
2067-Bfree(bd);
2068-Bfree(bd0);
20692038 goto failed_malloc;
20702039 }
20712040if (cmp(delta, bs) > 0)
@@ -2167,11 +2136,6 @@ _Py_dg_strtod(const char *s00, char **se)
21672136if ((word0(&rv) & Exp_mask) >=
21682137Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
21692138if (word0(&rv0) == Big0 && word1(&rv0) == Big1) {
2170-Bfree(bb);
2171-Bfree(bd);
2172-Bfree(bs);
2173-Bfree(bd0);
2174-Bfree(delta);
21752139 goto ovfl;
21762140 }
21772141word0(&rv) = Big0;
@@ -2213,16 +2177,11 @@ _Py_dg_strtod(const char *s00, char **se)
22132177 }
22142178 }
22152179cont:
2216-Bfree(bb);
2217-Bfree(bd);
2218-Bfree(bs);
2219-Bfree(delta);
2180+Bfree(bb); bb = NULL;
2181+Bfree(bd); bd = NULL;
2182+Bfree(bs); bs = NULL;
2183+Bfree(delta); delta = NULL;
22202184 }
2221-Bfree(bb);
2222-Bfree(bd);
2223-Bfree(bs);
2224-Bfree(bd0);
2225-Bfree(delta);
22262185if (bc.nd > nd) {
22272186error = bigcomp(&rv, s0, &bc);
22282187if (error)
@@ -2236,24 +2195,37 @@ _Py_dg_strtod(const char *s00, char **se)
22362195 }
2237219622382197ret:
2239-return sign ? -dval(&rv) : dval(&rv);
2198+result = sign ? -dval(&rv) : dval(&rv);
2199+ goto done;
2240220022412201parse_error:
2242-return 0.0;
2202+result = 0.0;
2203+ goto done;
2243220422442205failed_malloc:
22452206errno = ENOMEM;
2246-return -1.0;
2207+result = -1.0;
2208+ goto done;
2247220922482210undfl:
2249-return sign ? -0.0 : 0.0;
2211+result = sign ? -0.0 : 0.0;
2212+ goto done;
2250221322512214ovfl:
22522215errno = ERANGE;
22532216/* Can't trust HUGE_VAL */
22542217word0(&rv) = Exp_mask;
22552218word1(&rv) = 0;
2256-return sign ? -dval(&rv) : dval(&rv);
2219+result = sign ? -dval(&rv) : dval(&rv);
2220+ goto done;
2221+2222+done:
2223+Bfree(bb);
2224+Bfree(bd);
2225+Bfree(bs);
2226+Bfree(bd0);
2227+Bfree(delta);
2228+return result;
2257222922582230}
22592231