Make sure numeric command line arguments are actually numbers

This commit is contained in:
Eric Fischer
2018-02-26 17:35:39 -08:00
parent 45b1a1d9e0
commit e939a85251
+65 -20
View File
@@ -85,6 +85,7 @@ size_t CPUS;
size_t TEMP_FILES; size_t TEMP_FILES;
long long MAX_FILES; long long MAX_FILES;
static long long diskfree; static long long diskfree;
char **av;
void checkdisk(std::vector<struct reader> *r) { void checkdisk(std::vector<struct reader> *r) {
long long used = 0; long long used = 0;
@@ -101,11 +102,53 @@ void checkdisk(std::vector<struct reader> *r) {
} }
}; };
int atoi_require(const char *s, const char *what) {
char *err = NULL;
if (*s == '\0') {
fprintf(stderr, "%s: %s must be a number (got %s)\n", *av, what, s);
exit(EXIT_FAILURE);
}
int ret = strtol(s, &err, 10);
if (*err != '\0') {
fprintf(stderr, "%s: %s must be a number (got %s)\n", *av, what, s);
exit(EXIT_FAILURE);
}
return ret;
}
double atof_require(const char *s, const char *what) {
char *err = NULL;
if (*s == '\0') {
fprintf(stderr, "%s: %s must be a number (got %s)\n", *av, what, s);
exit(EXIT_FAILURE);
}
double ret = strtod(s, &err);
if (*err != '\0') {
fprintf(stderr, "%s: %s must be a number (got %s)\n", *av, what, s);
exit(EXIT_FAILURE);
}
return ret;
}
long long atoll_require(const char *s, const char *what) {
char *err = NULL;
if (*s == '\0') {
fprintf(stderr, "%s: %s must be a number (got %s)\n", *av, what, s);
exit(EXIT_FAILURE);
}
long long ret = strtoll(s, &err, 10);
if (*err != '\0') {
fprintf(stderr, "%s: %s must be a number (got %s)\n", *av, what, s);
exit(EXIT_FAILURE);
}
return ret;
}
void init_cpus() { void init_cpus() {
const char *TIPPECANOE_MAX_THREADS = getenv("TIPPECANOE_MAX_THREADS"); const char *TIPPECANOE_MAX_THREADS = getenv("TIPPECANOE_MAX_THREADS");
if (TIPPECANOE_MAX_THREADS != NULL) { if (TIPPECANOE_MAX_THREADS != NULL) {
CPUS = atoi(TIPPECANOE_MAX_THREADS); CPUS = atoi_require(TIPPECANOE_MAX_THREADS, "TIPPECANOE_MAX_THREADS");
} else { } else {
CPUS = sysconf(_SC_NPROCESSORS_ONLN); CPUS = sysconf(_SC_NPROCESSORS_ONLN);
} }
@@ -2245,6 +2288,7 @@ int main(int argc, char **argv) {
mtrace(); mtrace();
#endif #endif
av = argv;
init_cpus(); init_cpus();
extern int optind; extern int optind;
@@ -2483,12 +2527,12 @@ int main(int argc, char **argv) {
maxzoom = MAX_ZOOM; maxzoom = MAX_ZOOM;
guess_maxzoom = true; guess_maxzoom = true;
} else { } else {
maxzoom = atoi(optarg); maxzoom = atoi_require(optarg, "Maxzoom");
} }
break; break;
case 'Z': case 'Z':
minzoom = atoi(optarg); minzoom = atoi_require(optarg, "Minzoom");
break; break;
case 'R': { case 'R': {
@@ -2502,6 +2546,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "--one-tile argument must be z/x/y\n"); fprintf(stderr, "--one-tile argument must be z/x/y\n");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
break;
} }
case 'B': case 'B':
@@ -2510,16 +2555,16 @@ int main(int argc, char **argv) {
} else if (optarg[0] == 'g' || optarg[0] == 'f') { } else if (optarg[0] == 'g' || optarg[0] == 'f') {
basezoom = -2; basezoom = -2;
if (optarg[0] == 'g') { if (optarg[0] == 'g') {
basezoom_marker_width = atof(optarg + 1); basezoom_marker_width = atof_require(optarg + 1, "Marker width");
} else { } else {
basezoom_marker_width = sqrt(50000 / atof(optarg + 1)); basezoom_marker_width = sqrt(50000 / atof_require(optarg + 1, "Marker width"));
} }
if (basezoom_marker_width == 0 || atof(optarg + 1) == 0) { if (basezoom_marker_width == 0 || atof_require(optarg + 1, "Marker width") == 0) {
fprintf(stderr, "%s: Must specify value >0 with -B%c\n", argv[0], optarg[0]); fprintf(stderr, "%s: Must specify value >0 with -B%c\n", argv[0], optarg[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else { } else {
basezoom = atoi(optarg); basezoom = atoi_require(optarg, "Basezoom");
if (basezoom == 0 && strcmp(optarg, "0") != 0) { if (basezoom == 0 && strcmp(optarg, "0") != 0) {
fprintf(stderr, "%s: Couldn't understand -B%s\n", argv[0], optarg); fprintf(stderr, "%s: Couldn't understand -B%s\n", argv[0], optarg);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@@ -2528,7 +2573,7 @@ int main(int argc, char **argv) {
break; break;
case 'K': case 'K':
cluster_distance = atoi(optarg); cluster_distance = atoi_require(optarg, "Cluster distance");
if (cluster_distance > 255) { if (cluster_distance > 255) {
fprintf(stderr, "%s: --cluster-distance %d is too big; limit is 255\n", argv[0], cluster_distance); fprintf(stderr, "%s: --cluster-distance %d is too big; limit is 255\n", argv[0], cluster_distance);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@@ -2536,15 +2581,15 @@ int main(int argc, char **argv) {
break; break;
case 'd': case 'd':
full_detail = atoi(optarg); full_detail = atoi_require(optarg, "Full detail");
break; break;
case 'D': case 'D':
low_detail = atoi(optarg); low_detail = atoi_require(optarg, "Low detail");
break; break;
case 'm': case 'm':
min_detail = atoi(optarg); min_detail = atoi_require(optarg, "Min detail");
break; break;
case 'o': case 'o':
@@ -2598,21 +2643,21 @@ int main(int argc, char **argv) {
} else if (optarg[0] == 'g' || optarg[0] == 'f') { } else if (optarg[0] == 'g' || optarg[0] == 'f') {
droprate = -2; droprate = -2;
if (optarg[0] == 'g') { if (optarg[0] == 'g') {
basezoom_marker_width = atof(optarg + 1); basezoom_marker_width = atof_require(optarg + 1, "Marker width");
} else { } else {
basezoom_marker_width = sqrt(50000 / atof(optarg + 1)); basezoom_marker_width = sqrt(50000 / atof_require(optarg + 1, "Marker width"));
} }
if (basezoom_marker_width == 0 || atof(optarg + 1) == 0) { if (basezoom_marker_width == 0 || atof_require(optarg + 1, "Marker width") == 0) {
fprintf(stderr, "%s: Must specify value >0 with -r%c\n", argv[0], optarg[0]); fprintf(stderr, "%s: Must specify value >0 with -r%c\n", argv[0], optarg[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} else { } else {
droprate = atof(optarg); droprate = atof_require(optarg, "Drop rate");
} }
break; break;
case 'b': case 'b':
buffer = atoi(optarg); buffer = atoi_require(optarg, "Buffer");
break; break;
case 'f': case 'f':
@@ -2631,7 +2676,7 @@ int main(int argc, char **argv) {
break; break;
case 'g': case 'g':
gamma = atof(optarg); gamma = atof_require(optarg, "Gamma");
break; break;
case 'q': case 'q':
@@ -2679,7 +2724,7 @@ int main(int argc, char **argv) {
break; break;
case 'S': case 'S':
simplification = atof(optarg); simplification = atof_require(optarg, "Simplification");
if (simplification <= 0) { if (simplification <= 0) {
fprintf(stderr, "%s: --simplification must be > 0\n", argv[0]); fprintf(stderr, "%s: --simplification must be > 0\n", argv[0]);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@@ -2687,11 +2732,11 @@ int main(int argc, char **argv) {
break; break;
case 'M': case 'M':
max_tile_size = atoll(optarg); max_tile_size = atoll_require(optarg, "Max tile size");
break; break;
case 'O': case 'O':
max_tile_features = atoll(optarg); max_tile_features = atoll_require(optarg, "Max tile features");
break; break;
case 'c': case 'c':