Skip to content

Commit 3da7fe8

Browse files
committed
bfstd: New xstrtoll() wrapper
1 parent 32d2525 commit 3da7fe8

File tree

3 files changed

+48
-15
lines changed

3 files changed

+48
-15
lines changed

src/bfstd.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,35 @@ const char *xgetprogname(void) {
209209
return cmd;
210210
}
211211

212+
int xstrtoll(const char *str, char **end, int base, long long *value) {
213+
// strtoll() skips leading spaces, but we want to reject them
214+
if (xisspace(str[0])) {
215+
errno = EINVAL;
216+
return -1;
217+
}
218+
219+
// If end is NULL, make sure the entire string is valid
220+
bool entire = !end;
221+
char *endp;
222+
if (!end) {
223+
end = &endp;
224+
}
225+
226+
errno = 0;
227+
long long result = strtoll(str, end, base);
228+
if (errno != 0) {
229+
return -1;
230+
}
231+
232+
if (*end == str || (entire && **end != '\0')) {
233+
errno = EINVAL;
234+
return -1;
235+
}
236+
237+
*value = result;
238+
return 0;
239+
}
240+
212241
/** Compile and execute a regular expression for xrpmatch(). */
213242
static int xrpregex(nl_item item, const char *response) {
214243
const char *pattern = nl_langinfo(item);

src/bfstd.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,23 @@ int open_cterm(int flags);
178178
*/
179179
const char *xgetprogname(void);
180180

181+
/**
182+
* Wrapper for strtoll() that forbids leading spaces.
183+
*
184+
* @param str
185+
* The string to parse.
186+
* @param end
187+
* If non-NULL, will hold a pointer to the first invalid character.
188+
* If NULL, the entire string must be valid.
189+
* @param base
190+
* The base for the conversion, or 0 to auto-detect.
191+
* @param value
192+
* Will hold the parsed integer value, on success.
193+
* @return
194+
* 0 on success, -1 on failure.
195+
*/
196+
int xstrtoll(const char *str, char **end, int base, long long *value);
197+
181198
/**
182199
* Process a yes/no prompt.
183200
*

src/parse.c

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -526,34 +526,21 @@ enum int_flags {
526526
* Parse an integer.
527527
*/
528528
static const char *parse_int(const struct bfs_parser *parser, char **arg, const char *str, void *result, enum int_flags flags) {
529-
// strtoll() skips leading spaces, but we want to reject them
530-
if (xisspace(str[0])) {
531-
goto bad;
532-
}
533-
534529
int base = flags & IF_BASE_MASK;
535530
if (base == 0) {
536531
base = 10;
537532
}
538533

539534
char *endptr;
540-
errno = 0;
541-
long long value = strtoll(str, &endptr, base);
542-
if (errno != 0) {
535+
long long value;
536+
if (xstrtoll(str, &endptr, base, &value) != 0) {
543537
if (errno == ERANGE) {
544538
goto range;
545539
} else {
546540
goto bad;
547541
}
548542
}
549543

550-
// https://github.com/llvm/llvm-project/issues/64946
551-
sanitize_init(&endptr);
552-
553-
if (endptr == str) {
554-
goto bad;
555-
}
556-
557544
if (!(flags & IF_PARTIAL_OK) && *endptr != '\0') {
558545
goto bad;
559546
}

0 commit comments

Comments
 (0)