Skip to content

Commit 269bf7d

Browse files
committed
off_t is a type for file size. Use ptrdiff_t as more suitable type.
vfprintf() returns int and may return negative value, e.g. if stderr is redirected. offset in print_error_arrow() is practically limited by single argument size (128 kb). However, this is not obvious, so let's print spaces in chunks avoiding char-by-char output to unbuffered stream. When strtoul() converts valid ULONG_MAX, errno value is irrelevant. Practicallu it is impossible that ULONG_MAX is valid boot id. However, let's distinguish range error from valid unsigned long conversion. strtoul() always updates *endptr, no need to initialize and check. Signed-off-by: Dmytro Bagrii <dimich.dmb@gmail.com>
1 parent af3ba33 commit 269bf7d

1 file changed

Lines changed: 28 additions & 28 deletions

File tree

src/efibootmgr.c

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <stdlib.h>
4343
#include <string.h>
4444
#include <stdint.h>
45+
#include <stddef.h>
4546
#include <sys/stat.h>
4647
#include <fcntl.h>
4748
#include <dirent.h>
@@ -730,21 +731,25 @@ is_current_entry(int b)
730731
}
731732

732733
static void
733-
print_error_arrow(char *buffer, off_t offset, char *fmt, ...)
734+
print_error_arrow(const char *buffer, ptrdiff_t offset, const char *fmt, ...)
734735
{
735736
va_list ap;
736-
size_t size;
737-
unsigned int i;
737+
int size;
738738

739739
va_start(ap, fmt);
740740
size = vfprintf(stderr, fmt, ap);
741741
va_end(ap);
742-
fprintf(stderr, " %s\n", buffer);
742+
fprintf(stderr, " %s\n ", buffer);
743+
744+
if (size > 0)
745+
offset += size;
746+
747+
while (offset > 0) {
748+
int width = offset > INT_MAX ? INT_MAX : offset;
749+
offset -= width;
750+
fprintf(stderr, "%*s", width, "");
751+
}
743752

744-
for (i = 0; i < size + 1; i++)
745-
fprintf(stderr, " ");
746-
for (i = 0; i < offset; i++)
747-
fprintf(stderr, " ");
748753
fprintf(stderr, "^\n");
749754
}
750755

@@ -761,8 +766,7 @@ parse_order(const char *prefix, char *buffer, uint16_t **order, size_t *length)
761766
while ((intptr_t)buf < end) {
762767
size_t comma = strcspn(buf, ",");
763768
if (comma == 0) {
764-
off_t offset = (intptr_t)buf - (intptr_t)buffer;
765-
print_error_arrow(buffer, offset, "Malformed %s order",
769+
print_error_arrow(buffer, buf - buffer, "Malformed %s order",
766770
prefix);
767771
exit(8);
768772
} else {
@@ -789,30 +793,28 @@ parse_order(const char *prefix, char *buffer, uint16_t **order, size_t *length)
789793
size_t comma = strcspn(buf, ",");
790794

791795
buf[comma] = '\0';
792-
char *endptr = NULL;
796+
char *endptr;
797+
errno = 0;
793798
result = strtoul(buf, &endptr, 16);
794799
if ((result == ULONG_MAX && errno == ERANGE) ||
795-
(endptr && *endptr != '\0')) {
796-
off_t offset = (intptr_t)endptr - (intptr_t)buffer;
797-
print_error_arrow(buffer, offset, "Invalid %s order",
800+
(*endptr != '\0')) {
801+
print_error_arrow(buffer, endptr - buffer, "Invalid %s order",
798802
prefix);
799803
free(data);
800804
exit(8);
801805
}
802806
if (result > 0xffff) {
803-
off_t offset = (intptr_t)buf - (intptr_t)buffer;
804807
warnx("Invalid %s order entry value: %lX", prefix,
805808
result);
806-
print_error_arrow(buffer, offset, "Invalid %s order",
809+
print_error_arrow(buffer, buf - buffer, "Invalid %s order",
807810
prefix);
808811
free(data);
809812
exit(8);
810813
}
811814

812815
/* make sure this is an existing entry */
813816
if (!is_current_entry(result)) {
814-
off_t offset = (intptr_t)buf - (intptr_t)buffer;
815-
print_error_arrow(buffer, offset,
817+
print_error_arrow(buffer, buf - buffer,
816818
"Invalid %s order entry value",
817819
prefix);
818820
warnx("entry %04lX does not exist", result);
@@ -1582,7 +1584,7 @@ parse_opts(int argc, char **argv)
15821584
opts.delete = 1;
15831585
break;
15841586
case 'b': {
1585-
char *endptr = NULL;
1587+
char *endptr;
15861588
unsigned long result;
15871589

15881590
if (!optarg) {
@@ -1591,12 +1593,11 @@ parse_opts(int argc, char **argv)
15911593
break;
15921594
}
15931595

1596+
errno = 0;
15941597
result = strtoul(optarg, &endptr, 16);
15951598
if ((result == ULONG_MAX && errno == ERANGE) ||
1596-
(endptr && *endptr != '\0')) {
1597-
off_t offset = (intptr_t)endptr
1598-
- (intptr_t)optarg;
1599-
print_error_arrow(optarg, offset,
1599+
(*endptr != '\0')) {
1600+
print_error_arrow(optarg, endptr - optarg,
16001601
"Invalid bootnum value");
16011602
conditional_error_reporter(opts.verbose >= 1,
16021603
1);
@@ -1723,7 +1724,7 @@ parse_opts(int argc, char **argv)
17231724
opts.delete_bootnext = 1;
17241725
break;
17251726
case 'n': {
1726-
char *endptr = NULL;
1727+
char *endptr;
17271728
unsigned long result;
17281729

17291730
if (!optarg) {
@@ -1732,12 +1733,11 @@ parse_opts(int argc, char **argv)
17321733
break;
17331734
}
17341735

1736+
errno = 0;
17351737
result = strtoul(optarg, &endptr, 16);
17361738
if ((result == ULONG_MAX && errno == ERANGE) ||
1737-
(endptr && *endptr != '\0')) {
1738-
off_t offset = (intptr_t)endptr
1739-
- (intptr_t)optarg;
1740-
print_error_arrow(optarg, offset,
1739+
(*endptr != '\0')) {
1740+
print_error_arrow(optarg, endptr - optarg,
17411741
"Invalid BootNext value");
17421742
conditional_error_reporter(opts.verbose >= 1,
17431743
1);

0 commit comments

Comments
 (0)