Skip to content

Commit ac0a833

Browse files
Merge pull request #2366 from d0sboots/fmpz_set
Fix some edge cases in fmpz_set_str
2 parents d8c51b2 + d33c534 commit ac0a833

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

src/fmpz/set_str.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,10 +202,6 @@ fmpz_set_str(fmpz_t res, const char * str, int base)
202202
slong slen, i;
203203
int neg = 0;
204204

205-
/* Let GMP handle unusual bases. */
206-
if (base != 10)
207-
return fmpz_set_str_fallback(res, str, base, 0);
208-
209205
/* Allow leading whitespace. */
210206
while (isspace(str[0]))
211207
str++;
@@ -214,8 +210,18 @@ fmpz_set_str(fmpz_t res, const char * str, int base)
214210
{
215211
str++;
216212
neg = 1;
213+
214+
while (isspace(str[0]))
215+
str++;
216+
/* Checked specially, otherwise GMP might handle the second minus */
217+
if (str[0] == '-')
218+
return -1;
217219
}
218220

221+
/* Let GMP handle unusual bases. */
222+
if (base != 10)
223+
return fmpz_set_str_fallback(res, str, base, neg);
224+
219225
slen = strlen(str);
220226

221227
/* Allow trailing whitespace. */

src/fmpz/test/t-set_str.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
#include "ulong_extras.h"
1515
#include "fmpz.h"
1616

17+
typedef struct
18+
{
19+
int base;
20+
const char* input;
21+
int rv;
22+
slong result;
23+
}
24+
testcases_t;
25+
1726
TEST_FUNCTION_START(fmpz_set_str, state)
1827
{
1928
int i;
@@ -119,5 +128,74 @@ TEST_FUNCTION_START(fmpz_set_str, state)
119128
mpz_clear(b);
120129
}
121130

131+
/* Test specific cases to ensure proper edge-case handling */
132+
testcases_t cases[] =
133+
{
134+
{10, "", -1, 0},
135+
{ 0, "", -1, 0},
136+
{10, "0", 0, 0},
137+
{ 0, "0", 0, 0},
138+
{10, "-", -1, 0},
139+
{ 0, "-", -1, 0},
140+
{10, "-0", 0, 0},
141+
{ 0, "-0", 0, 0},
142+
{10, "- 2", 0, -2},
143+
{ 0, "- 2", 0, -2},
144+
{10, " -2", 0, -2},
145+
{ 0, " -2", 0, -2},
146+
{10, " - 2", 0, -2},
147+
{ 0, " - 2", 0, -2},
148+
{10, "- 2", 0, -2},
149+
{ 0, "- 2", 0, -2},
150+
{10, "- 2 ", 0, -2},
151+
{ 0, "- 2 ", 0, -2},
152+
{10, "--2", -1, 0},
153+
{ 0, "--2", -1, 0},
154+
{10, "1 2 3", 0, 123},
155+
{ 0, "1 2 3", 0, 123},
156+
{10, "1-2", -1, 0},
157+
{ 0, "1-2", -1, 0},
158+
{10, "f", -1, 0},
159+
{ 0, "f", -1, 0},
160+
{ 0, "0x0", 0, 0},
161+
{ 0, "-0x0", 0, 0},
162+
{ 0, "0xf", 0, 15},
163+
{ 0, "-0xf", 0, -15},
164+
{ 0, "--0xf", -1, 0},
165+
{ 0, "0x f", 0, 15},
166+
{ 0, "-0x f", 0, -15},
167+
{ 0, "- 0x f", 0, -15},
168+
{ 0, "0 xf", -1, 0},
169+
{16, "0x10", -1, 0},
170+
{ 0, "0x10", 0, 16},
171+
{ 2, "0b10", -1, 0},
172+
{ 0, "0b10", 0, 2},
173+
{ 8, "010", 0, 8},
174+
{ 0, "010", 0, 8},
175+
{10, "010", 0, 10},
176+
};
177+
for (i = 0; i < sizeof(cases) / sizeof(cases[0]); i++)
178+
{
179+
fmpz_t a;
180+
int ret;
181+
182+
fmpz_init(a);
183+
ret = fmpz_set_str(a, cases[i].input, cases[i].base);
184+
185+
if (ret != cases[i].rv || ret == 0 && fmpz_get_si(a) != cases[i].result)
186+
{
187+
flint_printf("FAIL:\n");
188+
flint_printf("case = %d\n", i);
189+
flint_printf("base = %d, str = %s\n", cases[i].base, cases[i].input);
190+
flint_printf("rv = %d, expected = %d\n", ret, cases[i].rv);
191+
flint_printf("result = "); fmpz_print(a);
192+
flint_printf(", expected = %ld\n", cases[i].result);
193+
fflush(stdout);
194+
flint_abort();
195+
}
196+
197+
fmpz_clear(a);
198+
}
199+
122200
TEST_FUNCTION_END(state);
123201
}

0 commit comments

Comments
 (0)