From a63bdfa317d6c4c0fdd0aff93de60c547712fd72 Mon Sep 17 00:00:00 2001 From: Christoph Raitzig Date: Sat, 1 Aug 2020 22:16:51 +0200 Subject: [PATCH] Fix: Buffer-overflow from unreasonable rgb-weights. Setting weights like --red=65532 --green=-65531 --blue=0 were valid (because they sum up to one), but cause a buffer-overflow when printing an image. This has been fixed and the weights system revised to be more user-friendly (weights do not have to sum up to one, that happens internally). See: https://github.com/cslarsen/jp2a/issues/12 --- configure.ac | 2 +- man/jp2a.1 | 3 +-- src/options.c | 21 ++++++++++++++++++--- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index b155ab7..40a526a 100644 --- a/configure.ac +++ b/configure.ac @@ -89,7 +89,7 @@ if test "x$enable_curl" = "xyes" ; then [ AC_MSG_WARN([required header file curl/curl.h not found, libcurl will be disabled (see --help)]) ]) fi -AC_CHECK_HEADERS([fcntl.h curses.h term.h ncurses/term.h]) +AC_CHECK_HEADERS([fcntl.h curses.h term.h ncurses/term.h math.h]) if test "$enable_termlib" = "yes" ; then diff --git a/man/jp2a.1 b/man/jp2a.1 index 3913f1f..a7d1e5f 100644 --- a/man/jp2a.1 +++ b/man/jp2a.1 @@ -1,4 +1,4 @@ -.TH jp2a 1 "April 5, 2020" "version 1.1.0" "USER COMMANDS" +.TH jp2a 1 "August 1, 2020" "version 1.1.0" "USER COMMANDS" .SH NAME jp2a \- convert JPEG images to ASCII .SH SYNOPSIS @@ -117,7 +117,6 @@ a display with light characters on a dark background, you should invert the imag .TP .BI \-\-blue= ... When converting from RGB to grayscale, use the given weights to calculate luminance. -These three floating point values must add up to exactly 1.0. The default is red=0.2989, green=0.5866 and blue=0.1145. .TP .BI \-\-size= WIDTHxHEIGHT diff --git a/src/options.c b/src/options.c index 71cf776..6fbaafb 100644 --- a/src/options.c +++ b/src/options.c @@ -26,6 +26,8 @@ #include #endif +#include + #include "jp2a.h" #include "options.h" #include "terminal.h" @@ -172,8 +174,12 @@ void help() { fprintf(stderr, "Report bugs to <%s>\n", PACKAGE_BUGREPORT); } -void precalc_rgb(const float red, const float green, const float blue) { +void precalc_rgb(float red, float green, float blue) { int n; + float sum = red + green + blue; + red /= sum; + green /= sum; + blue /= sum; for ( n=0; n<256; ++n ) { RED[n] = ((float) n) * red / 255.0f; GREEN[n] = ((float) n) * green / 255.0f; @@ -369,8 +375,17 @@ void parse_options(int argc, char** argv) { exit(1); } - if ( (int)((redweight + greenweight + blueweight)*10000000.0f) != 10000000 ) { - fputs("Weights RED + GREEN + BLUE must equal 1.0\n", stderr); + if ( redweight < 0 || greenweight < 0 || blueweight < 0 ) { + fputs("Weights can't be negative.\n", stderr); + exit(1); + } + if ( !isfinite(redweight) || !isfinite(greenweight) || !isfinite(blueweight) ) { + // This can happen if a number can not be represented as floating point, e.g. 3e400. + fputs("Did not understand a weight - possibly to large.\n", stderr); + exit(1); + } + if ( (redweight + greenweight + blueweight) == 0.0 ) { + fputs("At least one weight must be non-zero.\n", stderr); exit(1); }