diff --git a/src/apps/proj.cpp b/src/apps/proj.cpp index eeaaaceb8f..c3e5b1c57d 100644 --- a/src/apps/proj.cpp +++ b/src/apps/proj.cpp @@ -172,13 +172,13 @@ static void process(FILE *fid) { } if (reverseout) { - (void)printf(oform, data.uv.v); + limited_fprintf_for_number(stdout, oform, data.uv.v); putchar('\t'); - (void)printf(oform, data.uv.u); + limited_fprintf_for_number(stdout, oform, data.uv.u); } else { - (void)printf(oform, data.uv.u); + limited_fprintf_for_number(stdout, oform, data.uv.u); putchar('\t'); - (void)printf(oform, data.uv.v); + limited_fprintf_for_number(stdout, oform, data.uv.v); } } @@ -305,11 +305,11 @@ static void vprocess(FILE *fid) { (void)printf(" [ %.11g ]\n", dat_ll.phi * RAD_TO_DEG); (void)fputs(swapAxisCrs ? "Northing (y): " : "Easting (x): ", stdout); - (void)printf(oform, dat_xy.x); + limited_fprintf_for_number(stdout, oform, dat_xy.x); putchar('\n'); (void)fputs(swapAxisCrs ? "Easting (x): " : "Northing (y): ", stdout); - (void)printf(oform, dat_xy.y); + limited_fprintf_for_number(stdout, oform, dat_xy.y); putchar('\n'); (void)printf("Meridian scale (h) : %.8f ( %.4g %% error )\n", facs.meridional_scale, @@ -670,13 +670,15 @@ int main(int argc, char **argv) { (void)printf("#Final Earth figure: "); if (Proj->es != 0.0) { (void)printf("ellipsoid\n# Major axis (a): "); - (void)printf(oform ? oform : "%.3f", Proj->a); + limited_fprintf_for_number(stdout, oform ? oform : "%.3f", + Proj->a); (void)printf("\n# 1/flattening: %.6f\n", 1. / (1. - sqrt(1. - Proj->es))); (void)printf("# squared eccentricity: %.12f\n", Proj->es); } else { (void)printf("sphere\n# Radius: "); - (void)printf(oform ? oform : "%.3f", Proj->a); + limited_fprintf_for_number(stdout, oform ? oform : "%.3f", + Proj->a); (void)putchar('\n'); } } diff --git a/src/apps/utils.cpp b/src/apps/utils.cpp index 6d29a8c6b3..5c52d297ad 100644 --- a/src/apps/utils.cpp +++ b/src/apps/utils.cpp @@ -28,6 +28,7 @@ #include "utils.h" +#include #include bool validate_form_string_for_numbers(const char *formatString) { @@ -36,7 +37,7 @@ bool validate_form_string_for_numbers(const char *formatString) { if (formatString[0] != '%') valid = false; else { - auto oformLen = strlen(formatString); + const auto oformLen = strlen(formatString); for (int i = 1; i < static_cast(oformLen) - 1; i++) { if (!(formatString[i] == '.' || formatString[i] == '+' || (formatString[i] >= '0' && formatString[i] <= '9'))) { @@ -55,3 +56,41 @@ bool validate_form_string_for_numbers(const char *formatString) { } return valid; } + +void limited_fprintf_for_number(FILE *f, const char *formatString, double val) { + constexpr int BUFFER_SIZE = 32; + if (!validate_form_string_for_numbers(formatString) || + strlen(formatString) + 1 >= BUFFER_SIZE) { + fprintf(stderr, "Wrong formatString\n"); + return; + } + // Little-trick to bypass CodeSQL cpp/tainted-format-string check... + char szFormatingString[BUFFER_SIZE]; + int nLen = 0; + const auto oformLen = strlen(formatString); + szFormatingString[nLen++] = '%'; + for (int i = 1; i < static_cast(oformLen) - 1; i++) { + if (formatString[i] == '.') { + szFormatingString[nLen++] = '.'; + } else if (formatString[i] == '+') { + szFormatingString[nLen++] = '+'; + } else if (formatString[i] >= '0' && formatString[i] <= '9') { + szFormatingString[nLen++] = '0' + (formatString[i] - '0'); + } + } + if (formatString[oformLen - 1] == 'e') { + szFormatingString[nLen++] = 'e'; + } else if (formatString[oformLen - 1] == 'E') { + szFormatingString[nLen++] = 'E'; + } else if (formatString[oformLen - 1] == 'f') { + szFormatingString[nLen++] = 'f'; + } else if (formatString[oformLen - 1] == 'F') { + szFormatingString[nLen++] = 'F'; + } else if (formatString[oformLen - 1] == 'g') { + szFormatingString[nLen++] = 'g'; + } else if (formatString[oformLen - 1] == 'G') { + szFormatingString[nLen++] = 'G'; + } + szFormatingString[nLen++] = 0; + fprintf(f, szFormatingString, val); +} diff --git a/src/apps/utils.h b/src/apps/utils.h index 8cb99a860f..81d635681a 100644 --- a/src/apps/utils.h +++ b/src/apps/utils.h @@ -26,4 +26,8 @@ * DEALINGS IN THE SOFTWARE. ****************************************************************************/ +#include + bool validate_form_string_for_numbers(const char *formatString); + +void limited_fprintf_for_number(FILE *f, const char *formatString, double val);