VYPR
Medium severity6.5NVD Advisory· Published Sep 14, 2021· Updated Apr 24, 2026

CVE-2020-21050

CVE-2020-21050

Description

Libsixel prior to v1.8.3 contains a stack buffer overflow in the function gif_process_raster at fromgif.c.

Affected products

1

Patches

3
933670340dcd

Merge branch 'release'

https://github.com/saitoha/libsixelHayaki SaitoJan 3, 2020via osv
50 files changed · +2126 614
  • aclocal.m4+1 0 modified
    @@ -1647,6 +1647,7 @@ AC_SUBST([am__tar])
     AC_SUBST([am__untar])
     ]) # _AM_PROG_TAR
     
    +m4_include([m4/ax_gcc_builtin.m4])
     m4_include([m4/ax_gcc_func_attribute.m4])
     m4_include([m4/ax_gcc_var_attribute.m4])
     m4_include([m4/libtool.m4])
    
  • ChangeLog+192 0 modified
    @@ -1,5 +1,110 @@
    +2020-01-03  Hayaki Saito <saitoha@me.com>
    +
    +  * include/sixel.h.in, python/libsixel/__init__.py: Update python interface
    +
    +2020-01-01  Hayaki Saito <saitoha@me.com>
    +
    +  * .travis.yml: travis: drop "--with-gdk-pixbuf2" build on osx
    +
    +  * src/frame.c, src/fromsixel.c: Prevent an integer overflow problem(#127)
    +
    +2019-12-30  Hayaki Saito <saitoha@me.com>
    +
    +  * src/stb_image.h: Fix for CVE-2019-20056, assertion failure problem(#126).
    +  Thanks to @sleicasper
    +
    +2020-01-01  Hayaki Saito <saitoha@me.com>
    +
    +  * config.h.in, configure, configure.ac, src/allocator.c, src/chunk.c,
    +  src/decoder.c, src/dither.c, src/encoder.c, src/frame.c, src/fromgif.c,
    +  src/frompnm.c, src/fromsixel.c, src/loader.c, src/malloc_stub.c,
    +  src/output.c, src/pixelformat.c, src/quant.c, src/scale.c, src/status.c,
    +  src/tests.c, src/tosixel.c, src/tty.c, src/writer.c: Build fixes
    +
    +2019-12-31  Hayaki Saito <saitoha@me.com>
    +
    +  * Makefile.in, config.h.in, configure, configure.ac, src/chunk.c,
    +  src/decoder.c, src/fromsixel.c, src/malloc_stub.c, src/pixelformat.c,
    +  src/status.c, src/stb_image.h, src/tests.c, src/tosixel.c, src/tty.c: Minor
    +  update of configure checks
    +
    +2019-12-29  Hayaki Saito <saitoha@me.com>
    +
    +  * include/sixel.h.in, src/frompnm.c, src/writer.c: Add some input param
    +  checks to sixel_helper_write_image_file()
    +
    +  * src/tosixel.c: Add some input param checks to sixel_encode()
    +
    +  * ChangeLog: Update Changelog
    +
    +2019-12-28  Hayaki Saito <saitoha@me.com>
    +
    +  * src/encoder.c, src/loader.c, src/output.c, src/pixelformat.c: Strip
    +  trailing spaces
    +
    +  * configure, configure.ac, package.json: Bump version
    +
    +  * ChangeLog, Makefile.in: Update ChangeLog
    +
    +2019-12-27  Hayaki Saito <saitoha@me.com>
    +
    +  * Makefile.in, config.h.in, configure, configure.ac, src/loader.c: Avoid
    +  illegal longjump() call (#124)
    +
    +  * Makefile.in, configure, configure.ac: Strip unnecessary CFLAGS options
    +
    +2019-12-25  Hayaki Saito <saitoha@me.com>
    +
    +  * src/fromgif.c: GIF loader: avoid segfault caused by an integer overflow
    +  problem(#125, reported by @cuanduo).
    +
    +  * src/loader.c: Image loader: normalize requested colors to prevent integer
    +  overflow
    +
    +2019-12-23  Hayaki Saito <saitoha@me.com>
    +
    +  * include/sixel.h.in, src/allocator.c: Introduce SIXEL_ALLOCATE_BYTES_MAX
    +  macro and limit allocation size to 128MB(#74)
    +
    +  * src/fromgif.c: Minor fixes in load_gif().
    +
    +  * src/fromgif.c: GIF loader: check bad image separator, ensure left/top
    +  offset of image don't reach image margins (#122)
    +
    +  * include/sixel.h.in, src/fromgif.c: GIF loader: set default gif delay
    +
    +  * src/fromgif.c: GIF loader: skip unknown extension block
    +
    +  * src/fromgif.c: Avoid a buffer overflow problem on reading graphic control
    +  extension block
    +
    +  * Makefile.in, converters/Makefile.am, converters/Makefile.in,
    +  src/fromgif.c: GIF loader: consider frame-local color table for deciding the
    +  number of output colors
    +
    +  * src/fromgif.c: Strip first flag check in LZW compression function for
    +  issue #118
    +
    +2019-12-21  Hayaki Saito <saitoha@me.com>
    +
    +  * src/stb_image.h: Fix memory leak in STBI PSD loader
    +
    +2019-12-20  Hayaki Saito <saitoha@me.com>
    +
    +  * src/fromsixel.c: Fix memory leak problem in fromsixel.c (#120)
    +
    +2019-12-21  Hayaki Saito <saitoha@me.com>
    +
    +  * Makefile.am: Fix coveralls optoins
    +
    +  * src/dither.c: Fix broken unittest
    +
     2019-12-19  Hayaki Saito <saitoha@me.com>
     
    +  * NEWS: Update NEWS
    +
    +  * ChangeLog: Update ChangeLog
    +
       * src/fromsixel.c: sixel decoder: extend image width and height separately
     
     2019-12-18  Hayaki Saito <saitoha@me.com>
    @@ -69,6 +174,11 @@
       * src/dither.c: Avoid illegal memory access problem with 1 color paletted
       png(#73), Thanks to HongxuChen.
     
    +  * Makefile.in, aclocal.m4, configure, converters/Makefile.in,
    +  include/Makefile.in, m4/ax_gcc_builtin.m4, python/Makefile.in,
    +  src/Makefile.in, tools/Makefile.in: Add missing m4 macro
    +  m4/ax_gcc_builtin.m4
    +
       * README.md: Update README
     
       * README.md: Update README
    @@ -165,6 +275,8 @@
     
       * .travis.yml: Drop mingw32 build
     
    +  * .travis.yml: Ammend fix for e18ebe6
    +
       * .travis.yml: Drop mingw32 build
     
     2019-12-02  pwd <weidangpeng@gmail.com>
    @@ -287,6 +399,8 @@
       * src/decoder.c: Fix memory leak problems reported in #67
       https://github.com/saitoha/libsixel/issues/67
     
    +  * src/dither.c, src/encoder.c, src/quant.c: Add some comments
    +
       * src/dither.c, src/quant.c: Issue #68: check invalid color number(<1)
       https://github.com/saitoha/libsixel/issues/68
     
    @@ -296,8 +410,36 @@
       * src/frompnm.c: Prevent stack-buffer-overflow reported in #71
       https://github.com/saitoha/libsixel/issues/71
     
    +2018-06-25  Hayaki Saito <saitoha@me.com>
    +
    +  * src/stb_image.h: Prevent occurence of UndefinedBehaviorSanitizer in
    +  stb_image
    +
    +2018-06-19  Hayaki Saito <saitoha@me.com>
    +
    +  * Makefile.in, aclocal.m4, config.h.in, configure, configure.ac,
    +  converters/Makefile.in, include/Makefile.in, python/Makefile.in,
    +  src/Makefile.in, src/fromsixel.c, tools/Makefile.in: Add missing default
    +  case in RGB to HLS converter
    +
    +2018-06-18  Hayaki Saito <saitoha@me.com>
    +
    +  * README.md: Add ax_gcc_builtin.m4 for checking GCC built-in functions
    +
    +2018-06-17  Hayaki Saito <saitoha@me.com>
    +
    +  * src/encoder.c, src/loader.c, src/output.c, src/pixelformat.c: Strip
    +  trailing spaces
    +
    +2018-06-14  Hayaki Saito <saitoha@me.com>
    +
    +  * examples/opengl/main.c: example/opengl: use high level API,
    +  sixel_encoder_encode_bytes() instead of sixel_encode()
    +
     2018-06-10  Hayaki Saito <saitoha@me.com>
     
    +  * converters/img2sixel.1: Fix a typo: a_dither -> x_dither(issue #66)
    +
       * Makefile.in, config.h.in, configure, configure.ac, package.json: Bump
       version: 1.8.1
     
    @@ -438,8 +580,55 @@
       CODE IN LZW COMPRESSION" in [this
       document](https://www.w3.org/Graphics/GIF/spec-gif89a.txt).
     
    +2018-03-17  Hayaki Saito <saitoha@me.com>
    +
    +  * Makefile.in, aclocal.m4, compile, config.guess, config.sub, configure,
    +  converters/Makefile.in, depcomp, include/Makefile.in, install-sh, missing,
    +  py-compile, python/Makefile.in, src/Makefile.in, tools/Makefile.in: Update
    +  autotools version
    +
    +2017-06-22  Hayaki Saito <saitoha@me.com>
    +
    +  * src/fromsixel.c: Fix wrong HLS color handling
    +
    +2017-06-23  Hayaki Saito <saitoha@me.com>
    +
    +  * LICENSE.xterm, src/fromsixel.c: Rewrinte HLS handling function
    +  hls_to_rgb()
    +
    +  * include/sixel.h.in, src/dither.c, src/dither.h, src/quant.c, src/quant.h,
    +  src/tosixel.c: Introduce new meta type sixel_index_t (now equals unsigned
    +  char)
    +
    +  * src/output.h, src/tosixel.c: sixel_node_t::map should be represented as
    +  7bit character, not 8bit
    +
    +  * src/encoder.c, src/quant.c: Add annotations for some fixed buffer size
    +
    +  * src/dither.c, src/encoder.c, src/quant.c, src/tosixel.c: Respect to
    +  constant value SIXEL_PALETTE_MAX
    +
    +  * src/tosixel.c: Prevent HLS saturation parameter overflow(>100)
    +
    +2017-06-22  Hayaki Saito <saitoha@me.com>
    +
    +  * src/fromsixel.c: Fix wrong HLS color handling
    +
    +2017-06-10  Hayaki Saito <saitoha@me.com>
    +
    +  * README.md: Update README for adding some language bindings
    +
    +  * examples/drawing/main.c, examples/opengl/main.c, src/output.c: Example:
    +  Minor fixes
    +
    +2017-06-03  Hayaki Saito <saitoha@me.com>
    +
    +  * examples/opengl/main.c: demo/opengl: don't use deplecated API functions
    +
     2017-05-18  Hayaki Saito <saitoha@me.com>
     
    +  * README.md: README: add mention for forth-sixel
    +
       * converters/Makefile.am, converters/Makefile.in: Minor fixes
     
     2017-05-03  Hayaki Saito <saitoha@me.com>
    @@ -452,6 +641,9 @@
     
       * converters/img2sixel.c: Fix typo a_dither -> x_dither
     
    +  * README.md, converters/img2sixel.1, converters/img2sixel.c: Mark -D,
    +  --pipe-mode option as deprecated.
    +
       * .travis.yml: Reduce test cases for OSX.
     
       * src/encoder.c: Fix for Issue #57, lack of O_TRUNC when open() is called.
    
  • config.h.in+73 0 modified
    @@ -1,5 +1,8 @@
     /* config.h.in.  Generated from configure.ac by autoheader.  */
     
    +/* Define to 1 if you have the <assert.h> header file. */
    +#undef HAVE_ASSERT_H
    +
     /* define 1 if GCC supports -Bsymbolic */
     #undef HAVE_BSYMBOLIC
     
    @@ -12,6 +15,9 @@
     /* Define to 1 if you have the `clock' function. */
     #undef HAVE_CLOCK
     
    +/* Define to 1 if you have the <ctype.h> header file. */
    +#undef HAVE_CTYPE_H
    +
     /* enable debugging support */
     #undef HAVE_DEBUG
     
    @@ -114,6 +120,9 @@
     /* Define to 1 if you have the <fcntl.h> header file. */
     #undef HAVE_FCNTL_H
     
    +/* Define to 1 if you have the `floor' function. */
    +#undef HAVE_FLOOR
    +
     /* Define to 1 if the system has the `deprecated' function attribute */
     #undef HAVE_FUNC_ATTRIBUTE_DEPRECATED
     
    @@ -153,16 +162,28 @@
     /* Define to 1 if you have the `iconv' library (-liconv). */
     #undef HAVE_LIBICONV
     
    +/* Define to 1 if you have the `m' library (-lm). */
    +#undef HAVE_LIBM
    +
     /* whether libpng is available */
     #undef HAVE_LIBPNG
     
     /* Define to 1 if you have the <limits.h> header file. */
     #undef HAVE_LIMITS_H
     
    +/* Define to 1 if you have the `localeconv' function. */
    +#undef HAVE_LOCALECONV
    +
    +/* Define to 1 if you have the `longjmp' function. */
    +#undef HAVE_LONGJMP
    +
     /* Define to 1 if your system has a GNU libc compatible `malloc' function, and
        to 0 otherwise. */
     #undef HAVE_MALLOC
     
    +/* Define to 1 if you have the <math.h> header file. */
    +#undef HAVE_MATH_H
    +
     /* Define to 1 if you have the `memcpy' function. */
     #undef HAVE_MEMCPY
     
    @@ -172,6 +193,9 @@
     /* Define to 1 if you have the <memory.h> header file. */
     #undef HAVE_MEMORY_H
     
    +/* Define to 1 if you have the `memset' function. */
    +#undef HAVE_MEMSET
    +
     /* Define to 1 if you have the `nanosleep' function. */
     #undef HAVE_NANOSLEEP
     
    @@ -182,6 +206,9 @@
        and to 0 otherwise. */
     #undef HAVE_REALLOC
     
    +/* Define to 1 if you have the `select' function. */
    +#undef HAVE_SELECT
    +
     /* Define to 1 if you have the `setjmp' function. */
     #undef HAVE_SETJMP
     
    @@ -194,6 +221,9 @@
     /* Define to 1 if you have the <signal.h> header file. */
     #undef HAVE_SIGNAL_H
     
    +/* Define to 1 if you have the `sqrt' function. */
    +#undef HAVE_SQRT
    +
     /* Define to 1 if you have the `stat' function. */
     #undef HAVE_STAT
     
    @@ -203,6 +233,9 @@
     /* Define to 1 if you have the <stdlib.h> header file. */
     #undef HAVE_STDLIB_H
     
    +/* Define to 1 if you have the `strchr' function. */
    +#undef HAVE_STRCHR
    +
     /* Define to 1 if you have the `strdup' function. */
     #undef HAVE_STRDUP
     
    @@ -218,6 +251,9 @@
     /* Define to 1 if you have the `strncmp' function. */
     #undef HAVE_STRNCMP
     
    +/* Define to 1 if you have the `strstr' function. */
    +#undef HAVE_STRSTR
    +
     /* Define to 1 if you have the `strtol' function. */
     #undef HAVE_STRTOL
     
    @@ -260,9 +296,16 @@
     /* Define to 1 if the system has the `deprecated' variable attribute */
     #undef HAVE_VAR_ATTRIBUTE_DEPRECATED
     
    +/* Define to 1 if the system has the type `_Bool'. */
    +#undef HAVE__BOOL
    +
     /* Define to 1 if you have the `_setmode' function. */
     #undef HAVE__SETMODE
     
    +/* Define to 1 if the system has the `__builtin_unreachable' built-in function
    +   */
    +#undef HAVE___BUILTIN_UNREACHABLE
    +
     /* Define to the sub-directory where libtool stores uninstalled libraries. */
     #undef LT_OBJDIR
     
    @@ -293,8 +336,38 @@
     /* Version number of package */
     #undef VERSION
     
    +/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
    +   <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
    +   #define below would cause a syntax error. */
    +#undef _UINT32_T
    +
    +/* Define to `__inline__' or `__inline' if that's what the C compiler
    +   calls it, or to nothing if 'inline' is not supported under any name.  */
    +#ifndef __cplusplus
    +#undef inline
    +#endif
    +
    +/* Define to the type of a signed integer type of width exactly 16 bits if
    +   such a type exists and the standard includes do not define it. */
    +#undef int16_t
    +
    +/* Define to the type of a signed integer type of width exactly 32 bits if
    +   such a type exists and the standard includes do not define it. */
    +#undef int32_t
    +
     /* Define to rpl_malloc if the replacement function should be used. */
     #undef malloc
     
     /* Define to rpl_realloc if the replacement function should be used. */
     #undef realloc
    +
    +/* Define to `unsigned int' if <sys/types.h> does not define. */
    +#undef size_t
    +
    +/* Define to the type of an unsigned integer type of width exactly 16 bits if
    +   such a type exists and the standard includes do not define it. */
    +#undef uint16_t
    +
    +/* Define to the type of an unsigned integer type of width exactly 32 bits if
    +   such a type exists and the standard includes do not define it. */
    +#undef uint32_t
    
  • configure+862 61 modified
    @@ -1,6 +1,6 @@
     #! /bin/sh
     # Guess values for system-dependent variables and create Makefiles.
    -# Generated by GNU Autoconf 2.69 for sixel 1.8.4.
    +# Generated by GNU Autoconf 2.69 for sixel 1.8.5.
     #
     # Report bugs to <saitoha@me.com>.
     #
    @@ -590,8 +590,8 @@ MAKEFLAGS=
     # Identity of this package.
     PACKAGE_NAME='sixel'
     PACKAGE_TARNAME='sixel'
    -PACKAGE_VERSION='1.8.4'
    -PACKAGE_STRING='sixel 1.8.4'
    +PACKAGE_VERSION='1.8.5'
    +PACKAGE_STRING='sixel 1.8.5'
     PACKAGE_BUGREPORT='saitoha@me.com'
     PACKAGE_URL=''
     
    @@ -1393,7 +1393,7 @@ if test "$ac_init_help" = "long"; then
       # Omit some internal or obsolete options to make the list less imposing.
       # This message is too long to be a string in the A/UX 3.1 sh.
       cat <<_ACEOF
    -\`configure' configures sixel 1.8.4 to adapt to many kinds of systems.
    +\`configure' configures sixel 1.8.5 to adapt to many kinds of systems.
     
     Usage: $0 [OPTION]... [VAR=VALUE]...
     
    @@ -1463,7 +1463,7 @@ fi
     
     if test -n "$ac_init_help"; then
       case $ac_init_help in
    -     short | recursive ) echo "Configuration of sixel 1.8.4:";;
    +     short | recursive ) echo "Configuration of sixel 1.8.5:";;
        esac
       cat <<\_ACEOF
     
    @@ -1612,7 +1612,7 @@ fi
     test -n "$ac_init_help" && exit $ac_status
     if $ac_init_version; then
       cat <<\_ACEOF
    -sixel configure 1.8.4
    +sixel configure 1.8.5
     generated by GNU Autoconf 2.69
     
     Copyright (C) 2012 Free Software Foundation, Inc.
    @@ -1978,6 +1978,190 @@ fi
     
     } # ac_fn_c_check_header_mongrel
     
    +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
    +# -------------------------------------------
    +# Tests whether TYPE exists after having included INCLUDES, setting cache
    +# variable VAR accordingly.
    +ac_fn_c_check_type ()
    +{
    +  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
    +$as_echo_n "checking for $2... " >&6; }
    +if eval \${$3+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  eval "$3=no"
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +$4
    +int
    +main ()
    +{
    +if (sizeof ($2))
    +	 return 0;
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_compile "$LINENO"; then :
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +$4
    +int
    +main ()
    +{
    +if (sizeof (($2)))
    +	    return 0;
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_compile "$LINENO"; then :
    +
    +else
    +  eval "$3=yes"
    +fi
    +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +fi
    +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +fi
    +eval ac_res=\$$3
    +	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
    +$as_echo "$ac_res" >&6; }
    +  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
    +
    +} # ac_fn_c_check_type
    +
    +# ac_fn_c_find_intX_t LINENO BITS VAR
    +# -----------------------------------
    +# Finds a signed integer type with width BITS, setting cache variable VAR
    +# accordingly.
    +ac_fn_c_find_intX_t ()
    +{
    +  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
    +$as_echo_n "checking for int$2_t... " >&6; }
    +if eval \${$3+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  eval "$3=no"
    +     # Order is important - never check a type that is potentially smaller
    +     # than half of the expected target width.
    +     for ac_type in int$2_t 'int' 'long int' \
    +	 'long long int' 'short int' 'signed char'; do
    +       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +$ac_includes_default
    +	     enum { N = $2 / 2 - 1 };
    +int
    +main ()
    +{
    +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
    +test_array [0] = 0;
    +return test_array [0];
    +
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_compile "$LINENO"; then :
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +$ac_includes_default
    +	        enum { N = $2 / 2 - 1 };
    +int
    +main ()
    +{
    +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
    +		 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
    +test_array [0] = 0;
    +return test_array [0];
    +
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_compile "$LINENO"; then :
    +
    +else
    +  case $ac_type in #(
    +  int$2_t) :
    +    eval "$3=yes" ;; #(
    +  *) :
    +    eval "$3=\$ac_type" ;;
    +esac
    +fi
    +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +fi
    +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +       if eval test \"x\$"$3"\" = x"no"; then :
    +
    +else
    +  break
    +fi
    +     done
    +fi
    +eval ac_res=\$$3
    +	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
    +$as_echo "$ac_res" >&6; }
    +  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
    +
    +} # ac_fn_c_find_intX_t
    +
    +# ac_fn_c_find_uintX_t LINENO BITS VAR
    +# ------------------------------------
    +# Finds an unsigned integer type with width BITS, setting cache variable VAR
    +# accordingly.
    +ac_fn_c_find_uintX_t ()
    +{
    +  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5
    +$as_echo_n "checking for uint$2_t... " >&6; }
    +if eval \${$3+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  eval "$3=no"
    +     # Order is important - never check a type that is potentially smaller
    +     # than half of the expected target width.
    +     for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
    +	 'unsigned long long int' 'unsigned short int' 'unsigned char'; do
    +       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +$ac_includes_default
    +int
    +main ()
    +{
    +static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
    +test_array [0] = 0;
    +return test_array [0];
    +
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_compile "$LINENO"; then :
    +  case $ac_type in #(
    +  uint$2_t) :
    +    eval "$3=yes" ;; #(
    +  *) :
    +    eval "$3=\$ac_type" ;;
    +esac
    +fi
    +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +       if eval test \"x\$"$3"\" = x"no"; then :
    +
    +else
    +  break
    +fi
    +     done
    +fi
    +eval ac_res=\$$3
    +	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
    +$as_echo "$ac_res" >&6; }
    +  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
    +
    +} # ac_fn_c_find_uintX_t
    +
     # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
     # ---------------------------------------------
     # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
    @@ -2027,7 +2211,7 @@ cat >config.log <<_ACEOF
     This file contains any messages produced by compilers while
     running configure, to aid debugging if configure makes a mistake.
     
    -It was created by sixel $as_me 1.8.4, which was
    +It was created by sixel $as_me 1.8.5, which was
     generated by GNU Autoconf 2.69.  Invocation command line was
     
       $ $0 $@
    @@ -2970,7 +3154,7 @@ fi
     
     # Define the identity of the package.
      PACKAGE='sixel'
    - VERSION='1.8.4'
    + VERSION='1.8.5'
     
     
     cat >>confdefs.h <<_ACEOF
    @@ -12217,6 +12401,51 @@ if test x$ax_cv_have_func_attribute_deprecated != x; then
     
     fi
     
    +
    +
    +
    +    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_unreachable" >&5
    +$as_echo_n "checking for __builtin_unreachable... " >&6; }
    +if ${ax_cv_have___builtin_unreachable+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +
    +        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +
    +int
    +main ()
    +{
    +
    +            __builtin_unreachable()
    +
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_link "$LINENO"; then :
    +  ax_cv_have___builtin_unreachable=yes
    +else
    +  ax_cv_have___builtin_unreachable=no
    +fi
    +rm -f core conftest.err conftest.$ac_objext \
    +    conftest$ac_exeext conftest.$ac_ext
    +
    +fi
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have___builtin_unreachable" >&5
    +$as_echo "$ax_cv_have___builtin_unreachable" >&6; }
    +
    +    if test yes = $ax_cv_have___builtin_unreachable; then :
    +
    +cat >>confdefs.h <<_ACEOF
    +#define HAVE___BUILTIN_UNREACHABLE 1
    +_ACEOF
    +
    +fi
    +
    +
    +
    +
     CFLAGS_BACKUP=$CFLAGS
     CFLAGS="$CFLAGS -Werror"
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    @@ -12452,6 +12681,48 @@ fi
     
     
     # Checks for programs.
    +for ac_prog in gawk mawk nawk awk
    +do
    +  # Extract the first word of "$ac_prog", so it can be a program name with args.
    +set dummy $ac_prog; ac_word=$2
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    +$as_echo_n "checking for $ac_word... " >&6; }
    +if ${ac_cv_prog_AWK+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  if test -n "$AWK"; then
    +  ac_cv_prog_AWK="$AWK" # Let the user override the test.
    +else
    +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    +for as_dir in $PATH
    +do
    +  IFS=$as_save_IFS
    +  test -z "$as_dir" && as_dir=.
    +    for ac_exec_ext in '' $ac_executable_extensions; do
    +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    +    ac_cv_prog_AWK="$ac_prog"
    +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    +    break 2
    +  fi
    +done
    +  done
    +IFS=$as_save_IFS
    +
    +fi
    +fi
    +AWK=$ac_cv_prog_AWK
    +if test -n "$AWK"; then
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
    +$as_echo "$AWK" >&6; }
    +else
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
    +$as_echo "no" >&6; }
    +fi
    +
    +
    +  test -n "$AWK" && break
    +done
    +
     ac_ext=c
     ac_cpp='$CPP $CPPFLAGS'
     ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    @@ -13178,44 +13449,224 @@ else
     fi
     
     
    -
    -if test x$cross_compile != xyes; then :
    -
    -
    -
    -
    -
    -
    -
    -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
    -	if test -n "$ac_tool_prefix"; then
    -  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
    -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
    -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    -$as_echo_n "checking for $ac_word... " >&6; }
    -if ${ac_cv_path_PKG_CONFIG+:} false; then :
    +ac_ext=c
    +ac_cpp='$CPP $CPPFLAGS'
    +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
    +ac_compiler_gnu=$ac_cv_c_compiler_gnu
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
    +$as_echo_n "checking how to run the C preprocessor... " >&6; }
    +# On Suns, sometimes $CPP names a directory.
    +if test -n "$CPP" && test -d "$CPP"; then
    +  CPP=
    +fi
    +if test -z "$CPP"; then
    +  if ${ac_cv_prog_CPP+:} false; then :
       $as_echo_n "(cached) " >&6
     else
    -  case $PKG_CONFIG in
    -  [\\/]* | ?:[\\/]*)
    -  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
    -  ;;
    -  *)
    -  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    -for as_dir in $PATH
    +      # Double quotes because CPP needs to be expanded
    +    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
    +    do
    +      ac_preproc_ok=false
    +for ac_c_preproc_warn_flag in '' yes
     do
    -  IFS=$as_save_IFS
    -  test -z "$as_dir" && as_dir=.
    -    for ac_exec_ext in '' $ac_executable_extensions; do
    -  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    -    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
    -    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    -    break 2
    -  fi
    -done
    -  done
    -IFS=$as_save_IFS
    -
    +  # Use a header file that comes with gcc, so configuring glibc
    +  # with a fresh cross-compiler works.
    +  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
    +  # <limits.h> exists even on freestanding compilers.
    +  # On the NeXT, cc -E runs the code through the compiler's parser,
    +  # not just through cpp. "Syntax error" is here to catch this case.
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#ifdef __STDC__
    +# include <limits.h>
    +#else
    +# include <assert.h>
    +#endif
    +		     Syntax error
    +_ACEOF
    +if ac_fn_c_try_cpp "$LINENO"; then :
    +
    +else
    +  # Broken: fails on valid input.
    +continue
    +fi
    +rm -f conftest.err conftest.i conftest.$ac_ext
    +
    +  # OK, works on sane cases.  Now check whether nonexistent headers
    +  # can be detected and how.
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#include <ac_nonexistent.h>
    +_ACEOF
    +if ac_fn_c_try_cpp "$LINENO"; then :
    +  # Broken: success on invalid input.
    +continue
    +else
    +  # Passes both tests.
    +ac_preproc_ok=:
    +break
    +fi
    +rm -f conftest.err conftest.i conftest.$ac_ext
    +
    +done
    +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
    +rm -f conftest.i conftest.err conftest.$ac_ext
    +if $ac_preproc_ok; then :
    +  break
    +fi
    +
    +    done
    +    ac_cv_prog_CPP=$CPP
    +
    +fi
    +  CPP=$ac_cv_prog_CPP
    +else
    +  ac_cv_prog_CPP=$CPP
    +fi
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
    +$as_echo "$CPP" >&6; }
    +ac_preproc_ok=false
    +for ac_c_preproc_warn_flag in '' yes
    +do
    +  # Use a header file that comes with gcc, so configuring glibc
    +  # with a fresh cross-compiler works.
    +  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
    +  # <limits.h> exists even on freestanding compilers.
    +  # On the NeXT, cc -E runs the code through the compiler's parser,
    +  # not just through cpp. "Syntax error" is here to catch this case.
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#ifdef __STDC__
    +# include <limits.h>
    +#else
    +# include <assert.h>
    +#endif
    +		     Syntax error
    +_ACEOF
    +if ac_fn_c_try_cpp "$LINENO"; then :
    +
    +else
    +  # Broken: fails on valid input.
    +continue
    +fi
    +rm -f conftest.err conftest.i conftest.$ac_ext
    +
    +  # OK, works on sane cases.  Now check whether nonexistent headers
    +  # can be detected and how.
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#include <ac_nonexistent.h>
    +_ACEOF
    +if ac_fn_c_try_cpp "$LINENO"; then :
    +  # Broken: success on invalid input.
    +continue
    +else
    +  # Passes both tests.
    +ac_preproc_ok=:
    +break
    +fi
    +rm -f conftest.err conftest.i conftest.$ac_ext
    +
    +done
    +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
    +rm -f conftest.i conftest.err conftest.$ac_ext
    +if $ac_preproc_ok; then :
    +
    +else
    +  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
    +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
    +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
    +See \`config.log' for more details" "$LINENO" 5; }
    +fi
    +
    +ac_ext=c
    +ac_cpp='$CPP $CPPFLAGS'
    +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
    +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
    +ac_compiler_gnu=$ac_cv_c_compiler_gnu
    +
    +
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
    +$as_echo_n "checking whether ln -s works... " >&6; }
    +LN_S=$as_ln_s
    +if test "$LN_S" = "ln -s"; then
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    +$as_echo "yes" >&6; }
    +else
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
    +$as_echo "no, using $LN_S" >&6; }
    +fi
    +
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
    +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
    +set x ${MAKE-make}
    +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
    +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  cat >conftest.make <<\_ACEOF
    +SHELL = /bin/sh
    +all:
    +	@echo '@@@%%%=$(MAKE)=@@@%%%'
    +_ACEOF
    +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
    +case `${MAKE-make} -f conftest.make 2>/dev/null` in
    +  *@@@%%%=?*=@@@%%%*)
    +    eval ac_cv_prog_make_${ac_make}_set=yes;;
    +  *)
    +    eval ac_cv_prog_make_${ac_make}_set=no;;
    +esac
    +rm -f conftest.make
    +fi
    +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
    +$as_echo "yes" >&6; }
    +  SET_MAKE=
    +else
    +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
    +$as_echo "no" >&6; }
    +  SET_MAKE="MAKE=${MAKE-make}"
    +fi
    +
    +
    +if test x$cross_compile != xyes; then :
    +
    +
    +
    +
    +
    +
    +
    +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
    +	if test -n "$ac_tool_prefix"; then
    +  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
    +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
    +$as_echo_n "checking for $ac_word... " >&6; }
    +if ${ac_cv_path_PKG_CONFIG+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  case $PKG_CONFIG in
    +  [\\/]* | ?:[\\/]*)
    +  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
    +  ;;
    +  *)
    +  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
    +for as_dir in $PATH
    +do
    +  IFS=$as_save_IFS
    +  test -z "$as_dir" && as_dir=.
    +    for ac_exec_ext in '' $ac_executable_extensions; do
    +  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
    +    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
    +    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
    +    break 2
    +  fi
    +done
    +  done
    +IFS=$as_save_IFS
    +
       ;;
     esac
     fi
    @@ -13436,7 +13887,6 @@ _ACEOF
     if ac_fn_c_try_compile "$LINENO"; then :
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
     $as_echo "yes" >&6; }
    -                      AM_CFLAGS="$AM_CFLAGS -Wsign-conversion"
     
     $as_echo "#define HAVE_DIAGNOSTIC_SIGN_CONVERSION 1" >>confdefs.h
     
    @@ -13467,7 +13917,6 @@ _ACEOF
     if ac_fn_c_try_compile "$LINENO"; then :
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
     $as_echo "yes" >&6; }
    -                      AM_CFLAGS="$AM_CFLAGS -Wuninitialized"
     
     $as_echo "#define HAVE_DIAGNOSTIC_UNINITIALIZED 1" >>confdefs.h
     
    @@ -13498,7 +13947,6 @@ _ACEOF
     if ac_fn_c_try_compile "$LINENO"; then :
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
     $as_echo "yes" >&6; }
    -                      AM_CFLAGS="$AM_CFLAGS -Wstrict-overflow=1"
     
     $as_echo "#define HAVE_DIAGNOSTIC_STRICT_OVERFLOW 1" >>confdefs.h
     
    @@ -13529,7 +13977,6 @@ _ACEOF
     if ac_fn_c_try_compile "$LINENO"; then :
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
     $as_echo "yes" >&6; }
    -                      AM_CFLAGS="$AM_CFLAGS -Wshadow"
     
     $as_echo "#define HAVE_DIAGNOSTIC_SHADOW 1" >>confdefs.h
     
    @@ -13560,7 +14007,6 @@ _ACEOF
     if ac_fn_c_try_compile "$LINENO"; then :
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
     $as_echo "yes" >&6; }
    -                      AM_CFLAGS="$AM_CFLAGS -Wdouble-promotion"
     
     $as_echo "#define HAVE_DIAGNOSTIC_DOUBLE_PROMOTION 1" >>confdefs.h
     
    @@ -13591,7 +14037,6 @@ _ACEOF
     if ac_fn_c_try_compile "$LINENO"; then :
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
     $as_echo "yes" >&6; }
    -                      AM_CFLAGS="$AM_CFLAGS -Wswitch-default"
     
     $as_echo "#define HAVE_DIAGNOSTIC_SWITCH_DEFAULT 1" >>confdefs.h
     
    @@ -13622,7 +14067,6 @@ _ACEOF
     if ac_fn_c_try_compile "$LINENO"; then :
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
     $as_echo "yes" >&6; }
    -                      AM_CFLAGS="$AM_CFLAGS -Wunused-function"
     
     $as_echo "#define HAVE_DIAGNOSTIC_UNUSED_FUNCTION 1" >>confdefs.h
     
    @@ -13653,7 +14097,6 @@ _ACEOF
     if ac_fn_c_try_compile "$LINENO"; then :
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
     $as_echo "yes" >&6; }
    -                      AM_CFLAGS="$AM_CFLAGS -Wclobbered"
     
     $as_echo "#define HAVE_DIAGNOSTIC_CLOBBERED 1" >>confdefs.h
     
    @@ -13776,11 +14219,173 @@ done
     
     
     
    +# Check math library
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for floor in -lm" >&5
    +$as_echo_n "checking for floor in -lm... " >&6; }
    +if ${ac_cv_lib_m_floor+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  ac_check_lib_save_LIBS=$LIBS
    +LIBS="-lm  $LIBS"
    +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +
    +/* Override any GCC internal prototype to avoid an error.
    +   Use char because int might match the return type of a GCC
    +   builtin and then its argument prototype would still apply.  */
    +#ifdef __cplusplus
    +extern "C"
    +#endif
    +char floor ();
    +int
    +main ()
    +{
    +return floor ();
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_link "$LINENO"; then :
    +  ac_cv_lib_m_floor=yes
    +else
    +  ac_cv_lib_m_floor=no
    +fi
    +rm -f core conftest.err conftest.$ac_objext \
    +    conftest$ac_exeext conftest.$ac_ext
    +LIBS=$ac_check_lib_save_LIBS
    +fi
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_floor" >&5
    +$as_echo "$ac_cv_lib_m_floor" >&6; }
    +if test "x$ac_cv_lib_m_floor" = xyes; then :
    +  cat >>confdefs.h <<_ACEOF
    +#define HAVE_LIBM 1
    +_ACEOF
    +
    +  LIBS="-lm $LIBS"
    +
    +fi
    +
    +
     # Checks for libraries.
     
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
    +$as_echo_n "checking for ANSI C header files... " >&6; }
    +if ${ac_cv_header_stdc+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#include <stdlib.h>
    +#include <stdarg.h>
    +#include <string.h>
    +#include <float.h>
    +
    +int
    +main ()
    +{
    +
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_compile "$LINENO"; then :
    +  ac_cv_header_stdc=yes
    +else
    +  ac_cv_header_stdc=no
    +fi
    +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +
    +if test $ac_cv_header_stdc = yes; then
    +  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#include <string.h>
    +
    +_ACEOF
    +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
    +  $EGREP "memchr" >/dev/null 2>&1; then :
    +
    +else
    +  ac_cv_header_stdc=no
    +fi
    +rm -f conftest*
    +
    +fi
    +
    +if test $ac_cv_header_stdc = yes; then
    +  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#include <stdlib.h>
    +
    +_ACEOF
    +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
    +  $EGREP "free" >/dev/null 2>&1; then :
    +
    +else
    +  ac_cv_header_stdc=no
    +fi
    +rm -f conftest*
    +
    +fi
    +
    +if test $ac_cv_header_stdc = yes; then
    +  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
    +  if test "$cross_compiling" = yes; then :
    +  :
    +else
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#include <ctype.h>
    +#include <stdlib.h>
    +#if ((' ' & 0x0FF) == 0x020)
    +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
    +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
    +#else
    +# define ISLOWER(c) \
    +		   (('a' <= (c) && (c) <= 'i') \
    +		     || ('j' <= (c) && (c) <= 'r') \
    +		     || ('s' <= (c) && (c) <= 'z'))
    +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
    +#endif
    +
    +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
    +int
    +main ()
    +{
    +  int i;
    +  for (i = 0; i < 256; i++)
    +    if (XOR (islower (i), ISLOWER (i))
    +	|| toupper (i) != TOUPPER (i))
    +      return 2;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_run "$LINENO"; then :
    +
    +else
    +  ac_cv_header_stdc=no
    +fi
    +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
    +  conftest.$ac_objext conftest.beam conftest.$ac_ext
    +fi
    +
    +fi
    +fi
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
    +$as_echo "$ac_cv_header_stdc" >&6; }
    +if test $ac_cv_header_stdc = yes; then
    +
    +$as_echo "#define STDC_HEADERS 1" >>confdefs.h
    +
    +fi
    +
    +
     # Checks for header files.
    -for ac_header in memory.h \
    -                  stdlib.h \
    +for ac_header in assert.h \
    +                  math.h \
    +                  ctype.h \
    +                  memory.h \
                       string.h \
                       unistd.h \
                       stdint.h \
    @@ -13798,7 +14403,8 @@ for ac_header in memory.h \
                       sys/select.h \
                       sys/signal.h \
                       termios.h \
    -                  sys/ioctl.h
    +                  sys/ioctl.h \
    +                  inttypes.h
     do :
       as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
     ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
    @@ -13813,9 +14419,194 @@ done
     
     
     # Checks for typedefs, structures, and compiler characteristics.
    -#AC_CHECK_HEADER_STDBOOL
    -#AC_TYPE_SIZE_T
    -#AC_TYPE_UINT8_T
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
    +$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
    +if ${ac_cv_header_stdbool_h+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +
    +             #include <stdbool.h>
    +             #ifndef bool
    +              "error: bool is not defined"
    +             #endif
    +             #ifndef false
    +              "error: false is not defined"
    +             #endif
    +             #if false
    +              "error: false is not 0"
    +             #endif
    +             #ifndef true
    +              "error: true is not defined"
    +             #endif
    +             #if true != 1
    +              "error: true is not 1"
    +             #endif
    +             #ifndef __bool_true_false_are_defined
    +              "error: __bool_true_false_are_defined is not defined"
    +             #endif
    +
    +             struct s { _Bool s: 1; _Bool t; } s;
    +
    +             char a[true == 1 ? 1 : -1];
    +             char b[false == 0 ? 1 : -1];
    +             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
    +             char d[(bool) 0.5 == true ? 1 : -1];
    +             /* See body of main program for 'e'.  */
    +             char f[(_Bool) 0.0 == false ? 1 : -1];
    +             char g[true];
    +             char h[sizeof (_Bool)];
    +             char i[sizeof s.t];
    +             enum { j = false, k = true, l = false * true, m = true * 256 };
    +             /* The following fails for
    +                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
    +             _Bool n[m];
    +             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
    +             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
    +             /* Catch a bug in an HP-UX C compiler.  See
    +                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
    +                http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
    +              */
    +             _Bool q = true;
    +             _Bool *pq = &q;
    +
    +int
    +main ()
    +{
    +
    +             bool e = &s;
    +             *pq |= q;
    +             *pq |= ! q;
    +             /* Refer to every declared value, to avoid compiler optimizations.  */
    +             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
    +                     + !m + !n + !o + !p + !q + !pq);
    +
    +  ;
    +  return 0;
    +}
    +_ACEOF
    +if ac_fn_c_try_compile "$LINENO"; then :
    +  ac_cv_header_stdbool_h=yes
    +else
    +  ac_cv_header_stdbool_h=no
    +fi
    +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +fi
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
    +$as_echo "$ac_cv_header_stdbool_h" >&6; }
    +   ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
    +if test "x$ac_cv_type__Bool" = xyes; then :
    +
    +cat >>confdefs.h <<_ACEOF
    +#define HAVE__BOOL 1
    +_ACEOF
    +
    +
    +fi
    +
    +
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
    +$as_echo_n "checking for inline... " >&6; }
    +if ${ac_cv_c_inline+:} false; then :
    +  $as_echo_n "(cached) " >&6
    +else
    +  ac_cv_c_inline=no
    +for ac_kw in inline __inline__ __inline; do
    +  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    +/* end confdefs.h.  */
    +#ifndef __cplusplus
    +typedef int foo_t;
    +static $ac_kw foo_t static_foo () {return 0; }
    +$ac_kw foo_t foo () {return 0; }
    +#endif
    +
    +_ACEOF
    +if ac_fn_c_try_compile "$LINENO"; then :
    +  ac_cv_c_inline=$ac_kw
    +fi
    +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    +  test "$ac_cv_c_inline" != no && break
    +done
    +
    +fi
    +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
    +$as_echo "$ac_cv_c_inline" >&6; }
    +
    +case $ac_cv_c_inline in
    +  inline | yes) ;;
    +  *)
    +    case $ac_cv_c_inline in
    +      no) ac_val=;;
    +      *) ac_val=$ac_cv_c_inline;;
    +    esac
    +    cat >>confdefs.h <<_ACEOF
    +#ifndef __cplusplus
    +#define inline $ac_val
    +#endif
    +_ACEOF
    +    ;;
    +esac
    +
    +ac_fn_c_find_intX_t "$LINENO" "16" "ac_cv_c_int16_t"
    +case $ac_cv_c_int16_t in #(
    +  no|yes) ;; #(
    +  *)
    +
    +cat >>confdefs.h <<_ACEOF
    +#define int16_t $ac_cv_c_int16_t
    +_ACEOF
    +;;
    +esac
    +
    +ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
    +case $ac_cv_c_int32_t in #(
    +  no|yes) ;; #(
    +  *)
    +
    +cat >>confdefs.h <<_ACEOF
    +#define int32_t $ac_cv_c_int32_t
    +_ACEOF
    +;;
    +esac
    +
    +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
    +if test "x$ac_cv_type_size_t" = xyes; then :
    +
    +else
    +
    +cat >>confdefs.h <<_ACEOF
    +#define size_t unsigned int
    +_ACEOF
    +
    +fi
    +
    +ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t"
    +case $ac_cv_c_uint16_t in #(
    +  no|yes) ;; #(
    +  *)
    +
    +
    +cat >>confdefs.h <<_ACEOF
    +#define uint16_t $ac_cv_c_uint16_t
    +_ACEOF
    +;;
    +  esac
    +
    +ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t"
    +case $ac_cv_c_uint32_t in #(
    +  no|yes) ;; #(
    +  *)
    +
    +$as_echo "#define _UINT32_T 1" >>confdefs.h
    +
    +
    +cat >>confdefs.h <<_ACEOF
    +#define uint32_t $ac_cv_c_uint32_t
    +_ACEOF
    +;;
    +  esac
    +
     
     # Checks for library functions.
     for ac_header in stdlib.h
    @@ -13990,6 +14781,7 @@ fi
     
     for ac_func in memcpy \
                     memmove \
    +                memset \
                     setmode \
                     _setmode \
                     signal \
    @@ -14001,10 +14793,20 @@ for ac_func in memcpy \
                     clearerr \
                     stat \
                     setjmp \
    +                longjmp \
                     strerror \
                     isatty \
                     strncmp \
    -                ldiv
    +                ldiv \
    +                floor \
    +                localeconv \
    +                pow \
    +                select \
    +                sqrt \
    +                strchr \
    +                strerror \
    +                strstr \
    +                strtol
     do :
       as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
     ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
    @@ -14016,7 +14818,6 @@ _ACEOF
     fi
     done
     
    -
     # for HDR
     for ac_func in strtol pow
     do :
    @@ -16404,7 +17205,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
     # report actual input values of CONFIG_FILES etc. instead of their
     # values after options handling.
     ac_log="
    -This file was extended by sixel $as_me 1.8.4, which was
    +This file was extended by sixel $as_me 1.8.5, which was
     generated by GNU Autoconf 2.69.  Invocation command line was
     
       CONFIG_FILES    = $CONFIG_FILES
    @@ -16470,7 +17271,7 @@ _ACEOF
     cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
     ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
     ac_cs_version="\\
    -sixel config.status 1.8.4
    +sixel config.status 1.8.5
     configured by $0, generated by GNU Autoconf 2.69,
       with options \\"\$ac_cs_config\\"
     
    
  • configure.ac+46 25 modified
    @@ -3,7 +3,7 @@
     
     AC_PREREQ([2.60])
     LT_PREREQ([2.4])
    -AC_INIT([sixel], [1.8.4], [saitoha@me.com])
    +AC_INIT([sixel], [1.8.5], [saitoha@me.com])
     LS_LT_CURRENT=1
     LS_LT_REVISION=6
     LS_LT_AGE=0
    @@ -29,6 +29,8 @@ if test x$ax_cv_have_func_attribute_deprecated != x; then
         AC_SUBST(attr_func_deprecated, [__attribute__\(\(deprecated\)\)])
     fi
     
    +AX_GCC_BUILTIN([__builtin_unreachable])
    +
     CFLAGS_BACKUP=$CFLAGS
     CFLAGS="$CFLAGS -Werror"
     AC_TRY_COMPILE(
    @@ -166,8 +168,13 @@ AC_ARG_ENABLE([tests],
     AM_CONDITIONAL([COND_TESTS], [test x$enable_tests != xno])
     
     # Checks for programs.
    +AC_PROG_AWK
     AC_PROG_CC
    +AC_PROG_CPP
     AC_PROG_INSTALL
    +AC_PROG_LN_S
    +AC_PROG_MAKE_SET
    +
     AS_IF([test x$cross_compile != xyes], [PKG_PROG_PKG_CONFIG], [])
     
     AC_DEFUN([LS_CHECK_CFLAG], [
    @@ -188,29 +195,21 @@ LS_CHECK_CFLAG([-Wall],[AM_CFLAGS="$AM_CFLAGS -Wall"], [])
     LS_CHECK_CFLAG([-Wextra],[AM_CFLAGS="$AM_CFLAGS -Wextra"], [])
     LS_CHECK_CFLAG([-Wformat=2],[AM_CFLAGS="$AM_CFLAGS -Wformat=2"], [])
     LS_CHECK_CFLAG([-Wsign-conversion],
    -               [AM_CFLAGS="$AM_CFLAGS -Wsign-conversion"
    -                AC_DEFINE(HAVE_DIAGNOSTIC_SIGN_CONVERSION, 1, [define 1 if GCC supports -Wsign-conversion])])
    +               [AC_DEFINE(HAVE_DIAGNOSTIC_SIGN_CONVERSION, 1, [define 1 if GCC supports -Wsign-conversion])])
     LS_CHECK_CFLAG([-Wuninitialized],
    -               [AM_CFLAGS="$AM_CFLAGS -Wuninitialized"
    -                AC_DEFINE(HAVE_DIAGNOSTIC_UNINITIALIZED, 1, [define 1 if GCC supports -Wuninitialized])])
    +               [AC_DEFINE(HAVE_DIAGNOSTIC_UNINITIALIZED, 1, [define 1 if GCC supports -Wuninitialized])])
     LS_CHECK_CFLAG([-Wstrict-overflow],
    -               [AM_CFLAGS="$AM_CFLAGS -Wstrict-overflow=1"
    -                AC_DEFINE(HAVE_DIAGNOSTIC_STRICT_OVERFLOW, 1, [define 1 if GCC supports -Wstrict-overeflow=1])])
    +               [AC_DEFINE(HAVE_DIAGNOSTIC_STRICT_OVERFLOW, 1, [define 1 if GCC supports -Wstrict-overeflow=1])])
     LS_CHECK_CFLAG([-Wshadow],
    -               [AM_CFLAGS="$AM_CFLAGS -Wshadow"
    -                AC_DEFINE(HAVE_DIAGNOSTIC_SHADOW, 1, [define 1 if GCC supports -Wshadow])])
    +               [AC_DEFINE(HAVE_DIAGNOSTIC_SHADOW, 1, [define 1 if GCC supports -Wshadow])])
     LS_CHECK_CFLAG([-Wdouble-promotion],
    -               [AM_CFLAGS="$AM_CFLAGS -Wdouble-promotion"
    -                AC_DEFINE(HAVE_DIAGNOSTIC_DOUBLE_PROMOTION, 1, [define 1 if GCC supports -Wdouble-promotion])])
    +               [AC_DEFINE(HAVE_DIAGNOSTIC_DOUBLE_PROMOTION, 1, [define 1 if GCC supports -Wdouble-promotion])])
     LS_CHECK_CFLAG([-Wswitch-default],
    -               [AM_CFLAGS="$AM_CFLAGS -Wswitch-default"
    -                AC_DEFINE(HAVE_DIAGNOSTIC_SWITCH_DEFAULT, 1, [define 1 if GCC supports -Wswitch-default])])
    +               [AC_DEFINE(HAVE_DIAGNOSTIC_SWITCH_DEFAULT, 1, [define 1 if GCC supports -Wswitch-default])])
     LS_CHECK_CFLAG([-Wunused-function],
    -               [AM_CFLAGS="$AM_CFLAGS -Wunused-function"
    -                AC_DEFINE(HAVE_DIAGNOSTIC_UNUSED_FUNCTION, 1, [define 1 if GCC supports -Wunused-function])])
    +               [AC_DEFINE(HAVE_DIAGNOSTIC_UNUSED_FUNCTION, 1, [define 1 if GCC supports -Wunused-function])])
     LS_CHECK_CFLAG([-Wclobbered],
    -               [AM_CFLAGS="$AM_CFLAGS -Wclobbered"
    -                AC_DEFINE(HAVE_DIAGNOSTIC_CLOBBERED, 1, [define 1 if GCC supports -Wclobbered])])
    +               [AC_DEFINE(HAVE_DIAGNOSTIC_CLOBBERED, 1, [define 1 if GCC supports -Wclobbered])])
     LS_CHECK_CFLAG([-Bsymbolic],
                    [AM_CFLAGS="$AM_CFLAGS -Bsymbolic"
                     AC_DEFINE(HAVE_BSYMBOLIC, 1, [define 1 if GCC supports -Bsymbolic])])
    @@ -225,11 +224,18 @@ AC_SUBST([AM_CFLAGS])
     AC_CHECK_PROGS(MD5SUM, [md5sum md5])
     AC_SUBST(MD5SUM)
     
    +# Check math library
    +AC_CHECK_LIB([m], [floor])
    +
     # Checks for libraries.
     
    +AC_HEADER_STDC
    +
     # Checks for header files.
    -AC_CHECK_HEADERS([memory.h \
    -                  stdlib.h \
    +AC_CHECK_HEADERS([assert.h \
    +                  math.h \
    +                  ctype.h \
    +                  memory.h \
                       string.h \
                       unistd.h \
                       stdint.h \
    @@ -247,12 +253,17 @@ AC_CHECK_HEADERS([memory.h \
                       sys/select.h \
                       sys/signal.h \
                       termios.h \
    -                  sys/ioctl.h])
    +                  sys/ioctl.h \
    +                  inttypes.h])
     
     # Checks for typedefs, structures, and compiler characteristics.
    -#AC_CHECK_HEADER_STDBOOL
    -#AC_TYPE_SIZE_T
    -#AC_TYPE_UINT8_T
    +AC_CHECK_HEADER_STDBOOL
    +AC_C_INLINE
    +AC_TYPE_INT16_T
    +AC_TYPE_INT32_T
    +AC_TYPE_SIZE_T
    +AC_TYPE_UINT16_T
    +AC_TYPE_UINT32_T
     
     # Checks for library functions.
     AC_FUNC_MALLOC
    @@ -271,6 +282,7 @@ AM_CONDITIONAL([HAVE_GETOPT_LONG], [test x$have_getopt_long = xyes])
     
     AC_CHECK_FUNCS([memcpy \
                     memmove \
    +                memset \
                     setmode \
                     _setmode \
                     signal \
    @@ -282,11 +294,20 @@ AC_CHECK_FUNCS([memcpy \
                     clearerr \
                     stat \
                     setjmp \
    +                longjmp \
                     strerror \
                     isatty \
                     strncmp \
    -                ldiv])
    -
    +                ldiv \
    +                floor \
    +                localeconv \
    +                pow \
    +                select \
    +                sqrt \
    +                strchr \
    +                strerror \
    +                strstr \
    +                strtol])
     # for HDR
     AC_CHECK_FUNCS([strtol pow])
     
    
  • converters/img2sixel.1+2 2 modified
    @@ -258,8 +258,8 @@ rgb:rrrr/gggg/bbbb
     .B \-P, \-\-penetrate
     penetrate GNU Screen using DCS pass-through sequence.
     .TP 5
    -.B \-D, \-\-pipe\-mode (deprecated)
    -read source images from stdin continuously.
    +.B \-D, \-\-pipe\-mode
    +[[deprecated]] read source images from stdin continuously.
     .TP 5
     .B \-v, \-\-verbose
     show debugging info.
    
  • converters/img2sixel.c+3 3 modified
    @@ -303,8 +303,8 @@ void show_help(void)
                 "                             rgb:rrrr/gggg/bbbb\n"
                 "-P, --penetrate            penetrate GNU Screen using DCS\n"
                 "                           pass-through sequence\n"
    -            "-D, --pipe-mode            read source images from stdin\n"
    -            "                           continuously (deprecated)\n"
    +            "-D, --pipe-mode            [[deprecated]] read source images from\n"
    +            "                           stdin continuously\n"
                 "-v, --verbose              show debugging info\n"
                 "-V, --version              show version and license info\n"
                 "-H, --help                 show this help\n"
    @@ -380,7 +380,7 @@ main(int argc, char *argv[])
             {"encode-policy",    required_argument,  &long_opt, 'E'},
             {"bgcolor",          required_argument,  &long_opt, 'B'},
             {"complexion-score", required_argument,  &long_opt, 'C'},
    -        {"pipe-mode",        no_argument,        &long_opt, 'D'},
    +        {"pipe-mode",        no_argument,        &long_opt, 'D'}, /* deprecated */
             {"version",          no_argument,        &long_opt, 'V'},
             {"help",             no_argument,        &long_opt, 'H'},
             {0, 0, 0, 0}
    
  • converters/Makefile.am+3 3 modified
    @@ -84,10 +84,10 @@ if WANT_IMG2SIXEL
     	@echo '[test4] conversion options'
     	$(WINE) ./img2sixel $(top_srcdir)/images/snake.jpg -datkinson -flum -saverage | $(WINE) ./img2sixel | tee snake.sixel
     	$(WINE) ./img2sixel -w50% -h150% -dfs -Bblue -thls -shistogram < $(top_srcdir)/images/snake.jpg | tee snake2.sixel
    -	$(WINE) ./img2sixel -w2100 -h2100 -djajuni -bxterm256 -o snake3.sixel < $(top_srcdir)/images/snake.jpg
    +	$(WINE) ./img2sixel -w210 -h210 -djajuni -bxterm256 -o snake3.sixel < $(top_srcdir)/images/snake.jpg
     	$(WINE) ./img2sixel -w105% -h100 -B\#000000000 -rnearest < $(top_srcdir)/images/snake.gif
     	$(WINE) ./img2sixel -7 -sauto -w100 -rgaussian -qauto -dburkes -tauto $(top_srcdir)/images/snake.tga
    -	$(WINE) ./img2sixel -p300 -8 -scenter -Brgb:0/f/A -h100 -qfull -rhanning -dstucki -thls $(top_srcdir)/images/snake.tiff
    +	$(WINE) ./img2sixel -p200 -8 -scenter -Brgb:0/f/A -h100 -qfull -rhanning -dstucki -thls $(top_srcdir)/images/snake.tiff
     	$(WINE) ./img2sixel -8 -qauto -thls -e $(top_srcdir)/images/snake.pgm
     	$(WINE) ./img2sixel -8 -m $(top_srcdir)/images/map8-palette.png -Esize $(top_srcdir)/images/snake.ppm
     	$(WINE) ./img2sixel -7 -m $(top_srcdir)/images/map16-palette.png -Efast $(top_srcdir)/images/snake.jpg
    @@ -129,7 +129,7 @@ if WANT_IMG2SIXEL
     	$(WINE) ./img2sixel -p 1 -h100 -n1 $(top_srcdir)/images/snake.jpg && printf '\033[*1z'
     	$(WINE) ./img2sixel -e -h140 -rlanczos4 -P $(top_srcdir)/images/snake.jpg
     	$(WINE) ./img2sixel -e -i -P $(top_srcdir)/images/snake.jpg > /dev/null
    -	$(WINE) ./img2sixel -w2047 -h2047 $(top_srcdir)/images/snake.png | $(WINE) ./img2sixel > /dev/null
    +	$(WINE) ./img2sixel -w204 -h204 $(top_srcdir)/images/snake.png | $(WINE) ./img2sixel > /dev/null
     
     	@echo '[test5] DCS arguments handling'
     	seq 0 10 | while read i; do \
    
  • converters/Makefile.in+5 4 modified
    @@ -99,7 +99,8 @@ bin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
     subdir = converters
     SUBDIRS =
     ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
    +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_builtin.m4 \
    +	$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
     	$(top_srcdir)/m4/ax_gcc_var_attribute.m4 \
     	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
     	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
    @@ -1070,10 +1071,10 @@ test_impl:
     @WANT_IMG2SIXEL_TRUE@	@echo '[test4] conversion options'
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel $(top_srcdir)/images/snake.jpg -datkinson -flum -saverage | $(WINE) ./img2sixel | tee snake.sixel
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -w50% -h150% -dfs -Bblue -thls -shistogram < $(top_srcdir)/images/snake.jpg | tee snake2.sixel
    -@WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -w2100 -h2100 -djajuni -bxterm256 -o snake3.sixel < $(top_srcdir)/images/snake.jpg
    +@WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -w210 -h210 -djajuni -bxterm256 -o snake3.sixel < $(top_srcdir)/images/snake.jpg
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -w105% -h100 -B\#000000000 -rnearest < $(top_srcdir)/images/snake.gif
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -7 -sauto -w100 -rgaussian -qauto -dburkes -tauto $(top_srcdir)/images/snake.tga
    -@WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -p300 -8 -scenter -Brgb:0/f/A -h100 -qfull -rhanning -dstucki -thls $(top_srcdir)/images/snake.tiff
    +@WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -p200 -8 -scenter -Brgb:0/f/A -h100 -qfull -rhanning -dstucki -thls $(top_srcdir)/images/snake.tiff
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -8 -qauto -thls -e $(top_srcdir)/images/snake.pgm
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -8 -m $(top_srcdir)/images/map8-palette.png -Esize $(top_srcdir)/images/snake.ppm
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -7 -m $(top_srcdir)/images/map16-palette.png -Efast $(top_srcdir)/images/snake.jpg
    @@ -1115,7 +1116,7 @@ test_impl:
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -p 1 -h100 -n1 $(top_srcdir)/images/snake.jpg && printf '\033[*1z'
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -e -h140 -rlanczos4 -P $(top_srcdir)/images/snake.jpg
     @WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -e -i -P $(top_srcdir)/images/snake.jpg > /dev/null
    -@WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -w2047 -h2047 $(top_srcdir)/images/snake.png | $(WINE) ./img2sixel > /dev/null
    +@WANT_IMG2SIXEL_TRUE@	$(WINE) ./img2sixel -w204 -h204 $(top_srcdir)/images/snake.png | $(WINE) ./img2sixel > /dev/null
     
     @WANT_IMG2SIXEL_TRUE@	@echo '[test5] DCS arguments handling'
     @WANT_IMG2SIXEL_TRUE@	seq 0 10 | while read i; do \
    
  • examples/drawing/main.c+4 1 modified
    @@ -77,6 +77,7 @@ wait_stdin(int usec)
         return select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tv);
     }
     
    +
     static int
     scroll_on_demand(int pixelheight)
     {
    @@ -109,7 +110,9 @@ scroll_on_demand(int pixelheight)
         return 0;
     }
     
    -static int tty_raw(struct termios *old_termios)
    +/* set terminal into raw mode. */
    +static int
    +tty_raw(struct termios *old_termios)
     {
         struct termios new_termios;
         int ret;
    
  • examples/opengl/main.c+22 27 modified
    @@ -66,6 +66,7 @@
     #include <unistd.h>
     #include <memory.h>
     #include <math.h>
    +#include <errno.h>
     #if HAVE_TERMIOS_H
     # include <termios.h>
     #endif
    @@ -329,40 +330,27 @@ draw_scene(void)
     }
     
     
    -static int
    -sixel_write(char *data, int size, void *priv)
    -{
    -    return fwrite(data, 1, size, (FILE *)priv);
    -}
    -
    -
     static SIXELSTATUS
     output_sixel(unsigned char *pixbuf, int width, int height,
    -             int ncolors, int pixelformat)
    +             int pixelformat, int ncolors)
     {
    -    sixel_output_t *context;
    -    sixel_dither_t *dither;
    +    sixel_encoder_t *encoder;
         SIXELSTATUS status;
    +    char opt[256];
     
    -#if USE_OSMESA
    -    pixelformat = SIXEL_PIXELFORMAT_RGBA8888;
    -#endif
    -    context = sixel_output_create(sixel_write, stdout);
    -    dither = sixel_dither_create(ncolors);
    -    status = sixel_dither_initialize(dither, pixbuf,
    -                                     width, height,
    -                                     pixelformat,
    -                                     SIXEL_LARGE_AUTO,
    -                                     SIXEL_REP_AUTO,
    -                                     SIXEL_QUALITY_AUTO);
    +    status = sixel_encoder_new(&encoder, NULL);
    +    if (SIXEL_FAILED(status))
    +        return status;
    +    if (sprintf(opt, "%d", ncolors) <= 0)
    +        return SIXEL_LIBC_ERROR | (errno | 0xff);
    +    status = sixel_encoder_setopt(encoder, SIXEL_OPTFLAG_COLORS, opt);
         if (SIXEL_FAILED(status))
             return status;
    -    status = sixel_encode(pixbuf, width, height,
    -                          pixelformat, dither, context);
    +    status = sixel_encoder_encode_bytes(
    +        encoder, pixbuf, width, height, pixelformat, NULL, (-1));
         if (SIXEL_FAILED(status))
             return status;
    -    sixel_output_unref(context);
    -    sixel_dither_unref(dither);
    +    sixel_encoder_unref(encoder);
     
         return status;
     }
    @@ -503,13 +491,20 @@ main(int argc, char** argv)
                 break;
     
             printf("\0338");
    +        fflush(stdout);
     #if USE_OSMESA
             pixbuf = pbuffer;
     #else
             glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixbuf);
     #endif
    -        status = output_sixel(pixbuf, width, height, ncolors,
    -                              SIXEL_PIXELFORMAT_RGB888);
    +        status = output_sixel(
    +            pixbuf, width, height,
    +#if USE_OSMESA
    +            SIXEL_PIXELFORMAT_RGBA8888,
    +#else
    +            SIXEL_PIXELFORMAT_RGB888,
    +#endif
    +            ncolors);
             if (SIXEL_FAILED(status)) {
                 fprintf(stderr, "%s\n%s\n",
                         sixel_helper_format_error(status),
    
  • include/Makefile.in+2 1 modified
    @@ -90,7 +90,8 @@ build_triplet = @build@
     host_triplet = @host@
     subdir = include
     ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
    +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_builtin.m4 \
    +	$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
     	$(top_srcdir)/m4/ax_gcc_var_attribute.m4 \
     	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
     	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
    
  • include/sixel.h.in+18 12 modified
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2014-2018 Hayaki Saito
    + * Copyright (c) 2014-2020 Hayaki Saito
      *
      * Permission is hereby granted, free of charge, to any person obtaining a copy of
      * this software and associated documentation files (the "Software"), to deal in
    @@ -33,10 +33,19 @@
     #define LIBSIXEL_VERSION "@PACKAGE_VERSION@"
     #define LIBSIXEL_ABI_VERSION "@LS_LTVERSION@"
     
    +typedef unsigned char sixel_index_t;
    +
    +/* limitations */
     #define SIXEL_OUTPUT_PACKET_SIZE     16384
     #define SIXEL_PALETTE_MIN            2
     #define SIXEL_PALETTE_MAX            256
     #define SIXEL_USE_DEPRECATED_SYMBOLS 1
    +#define SIXEL_ALLOCATE_BYTES_MAX     10248UL * 1024UL * 128UL   /* up to 128M */
    +#define SIXEL_WIDTH_LIMIT            1000000
    +#define SIXEL_HEIGHT_LIMIT           1000000
    +
    +/* loader settings */
    +#define SIXEL_DEFALUT_GIF_DELAY         1
     
     /* return value */
     typedef int SIXELSTATUS;
    @@ -367,9 +376,6 @@ typedef int SIXELSTATUS;
     #define SIXEL_OPTFLAG_VERSION           ('V')  /* -V, --version: show version and license info */
     #define SIXEL_OPTFLAG_HELP              ('H')  /* -H, --help: show this help */
     
    -#define SIXEL_WIDTH_LIMIT               1000000
    -#define SIXEL_HEIGHT_LIMIT              1000000
    -
     #if SIXEL_USE_DEPRECATED_SYMBOLS
     /* output character size */
     enum characterSize {
    @@ -692,14 +698,14 @@ sixel_dither_unref(sixel_dither_t *dither); /* dither context object */
     /* initialize internal palette from specified pixel buffer */
     SIXELAPI SIXELSTATUS
     sixel_dither_initialize(
    -    sixel_dither_t *dither,          /* dither context object */
    -    unsigned char /* in */ *data,    /* sample image */
    -    int /* in */ width,              /* image width */
    -    int /* in */ height,             /* image height */
    -    int /* in */ pixelformat,        /* one of enum pixelFormat */
    -    int /* in */ method_for_largest, /* method for finding the largest dimension */
    -    int /* in */ method_for_rep,     /* method for choosing a color from the box */
    -    int /* in */ quality_mode);      /* quality of histogram processing */
    +    sixel_dither_t *dither,                    /* dither context object */
    +    unsigned char /* in */ *data,              /* sample image */
    +    int           /* in */ width,              /* image width */
    +    int           /* in */ height,             /* image height */
    +    int           /* in */ pixelformat,        /* one of enum pixelFormat */
    +    int           /* in */ method_for_largest, /* method for finding the largest dimension */
    +    int           /* in */ method_for_rep,     /* method for choosing a color from the box */
    +    int           /* in */ quality_mode);      /* quality of histogram processing */
     
     /* set diffusion type, choose from enum methodForDiffuse */
     SIXELAPI void
    
  • LICENSE.xterm+0 34 removed
    @@ -1,34 +0,0 @@
    -The helper function hls2rgb in src/fromsixel.c is imported from
    -graphics.c in Xterm pl#310 originally written by Ross Combs.
    -
    -http://invisible-island.net/xterm/
    -
    -
    -Copyright 2013,2014 by Ross Combs
    -
    -                        All Rights Reserved
    -
    -Permission is hereby granted, free of charge, to any person obtaining a
    -copy of this software and associated documentation files (the
    -"Software"), to deal in the Software without restriction, including
    -without limitation the rights to use, copy, modify, merge, publish,
    -distribute, sublicense, and/or sell copies of the Software, and to
    -permit persons to whom the Software is furnished to do so, subject to
    -the following conditions:
    -
    -The above copyright notice and this permission notice shall be included
    -in all copies or substantial portions of the Software.
    -
    -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    -OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    -IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
    -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    -
    -Except as contained in this notice, the name(s) of the above copyright
    -holders shall not be used in advertising or otherwise to promote the
    -sale, use or other dealings in this Software without prior written
    -authorization.
    -
    
  • m4/ax_gcc_builtin.m4+170 0 added
    @@ -0,0 +1,170 @@
    +# ===========================================================================
    +#      https://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html
    +# ===========================================================================
    +#
    +# SYNOPSIS
    +#
    +#   AX_GCC_BUILTIN(BUILTIN)
    +#
    +# DESCRIPTION
    +#
    +#   This macro checks if the compiler supports one of GCC's built-in
    +#   functions; many other compilers also provide those same built-ins.
    +#
    +#   The BUILTIN parameter is the name of the built-in function.
    +#
    +#   If BUILTIN is supported define HAVE_<BUILTIN>. Keep in mind that since
    +#   builtins usually start with two underscores they will be copied over
    +#   into the HAVE_<BUILTIN> definition (e.g. HAVE___BUILTIN_EXPECT for
    +#   __builtin_expect()).
    +#
    +#   The macro caches its result in the ax_cv_have_<BUILTIN> variable (e.g.
    +#   ax_cv_have___builtin_expect).
    +#
    +#   The macro currently supports the following built-in functions:
    +#
    +#    __builtin_assume_aligned
    +#    __builtin_bswap16
    +#    __builtin_bswap32
    +#    __builtin_bswap64
    +#    __builtin_choose_expr
    +#    __builtin___clear_cache
    +#    __builtin_clrsb
    +#    __builtin_clrsbl
    +#    __builtin_clrsbll
    +#    __builtin_clz
    +#    __builtin_clzl
    +#    __builtin_clzll
    +#    __builtin_complex
    +#    __builtin_constant_p
    +#    __builtin_ctz
    +#    __builtin_ctzl
    +#    __builtin_ctzll
    +#    __builtin_expect
    +#    __builtin_ffs
    +#    __builtin_ffsl
    +#    __builtin_ffsll
    +#    __builtin_fpclassify
    +#    __builtin_huge_val
    +#    __builtin_huge_valf
    +#    __builtin_huge_vall
    +#    __builtin_inf
    +#    __builtin_infd128
    +#    __builtin_infd32
    +#    __builtin_infd64
    +#    __builtin_inff
    +#    __builtin_infl
    +#    __builtin_isinf_sign
    +#    __builtin_nan
    +#    __builtin_nand128
    +#    __builtin_nand32
    +#    __builtin_nand64
    +#    __builtin_nanf
    +#    __builtin_nanl
    +#    __builtin_nans
    +#    __builtin_nansf
    +#    __builtin_nansl
    +#    __builtin_object_size
    +#    __builtin_parity
    +#    __builtin_parityl
    +#    __builtin_parityll
    +#    __builtin_popcount
    +#    __builtin_popcountl
    +#    __builtin_popcountll
    +#    __builtin_powi
    +#    __builtin_powif
    +#    __builtin_powil
    +#    __builtin_prefetch
    +#    __builtin_trap
    +#    __builtin_types_compatible_p
    +#    __builtin_unreachable
    +#
    +#   Unsupported built-ins will be tested with an empty parameter set and the
    +#   result of the check might be wrong or meaningless so use with care.
    +#
    +# LICENSE
    +#
    +#   Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
    +#
    +#   Copying and distribution of this file, with or without modification, are
    +#   permitted in any medium without royalty provided the copyright notice
    +#   and this notice are preserved.  This file is offered as-is, without any
    +#   warranty.
    +
    +#serial 6
    +
    +AC_DEFUN([AX_GCC_BUILTIN], [
    +    AS_VAR_PUSHDEF([ac_var], [ax_cv_have_$1])
    +
    +    AC_CACHE_CHECK([for $1], [ac_var], [
    +        AC_LINK_IFELSE([AC_LANG_PROGRAM([], [
    +            m4_case([$1],
    +                [__builtin_assume_aligned], [$1("", 0)],
    +                [__builtin_bswap16], [$1(0)],
    +                [__builtin_bswap32], [$1(0)],
    +                [__builtin_bswap64], [$1(0)],
    +                [__builtin_choose_expr], [$1(0, 0, 0)],
    +                [__builtin___clear_cache], [$1("", "")],
    +                [__builtin_clrsb], [$1(0)],
    +                [__builtin_clrsbl], [$1(0)],
    +                [__builtin_clrsbll], [$1(0)],
    +                [__builtin_clz], [$1(0)],
    +                [__builtin_clzl], [$1(0)],
    +                [__builtin_clzll], [$1(0)],
    +                [__builtin_complex], [$1(0.0, 0.0)],
    +                [__builtin_constant_p], [$1(0)],
    +                [__builtin_ctz], [$1(0)],
    +                [__builtin_ctzl], [$1(0)],
    +                [__builtin_ctzll], [$1(0)],
    +                [__builtin_expect], [$1(0, 0)],
    +                [__builtin_ffs], [$1(0)],
    +                [__builtin_ffsl], [$1(0)],
    +                [__builtin_ffsll], [$1(0)],
    +                [__builtin_fpclassify], [$1(0, 1, 2, 3, 4, 0.0)],
    +                [__builtin_huge_val], [$1()],
    +                [__builtin_huge_valf], [$1()],
    +                [__builtin_huge_vall], [$1()],
    +                [__builtin_inf], [$1()],
    +                [__builtin_infd128], [$1()],
    +                [__builtin_infd32], [$1()],
    +                [__builtin_infd64], [$1()],
    +                [__builtin_inff], [$1()],
    +                [__builtin_infl], [$1()],
    +                [__builtin_isinf_sign], [$1(0.0)],
    +                [__builtin_nan], [$1("")],
    +                [__builtin_nand128], [$1("")],
    +                [__builtin_nand32], [$1("")],
    +                [__builtin_nand64], [$1("")],
    +                [__builtin_nanf], [$1("")],
    +                [__builtin_nanl], [$1("")],
    +                [__builtin_nans], [$1("")],
    +                [__builtin_nansf], [$1("")],
    +                [__builtin_nansl], [$1("")],
    +                [__builtin_object_size], [$1("", 0)],
    +                [__builtin_parity], [$1(0)],
    +                [__builtin_parityl], [$1(0)],
    +                [__builtin_parityll], [$1(0)],
    +                [__builtin_popcount], [$1(0)],
    +                [__builtin_popcountl], [$1(0)],
    +                [__builtin_popcountll], [$1(0)],
    +                [__builtin_powi], [$1(0, 0)],
    +                [__builtin_powif], [$1(0, 0)],
    +                [__builtin_powil], [$1(0, 0)],
    +                [__builtin_prefetch], [$1("")],
    +                [__builtin_trap], [$1()],
    +                [__builtin_types_compatible_p], [$1(int, int)],
    +                [__builtin_unreachable], [$1()],
    +                [m4_warn([syntax], [Unsupported built-in $1, the test may fail])
    +                 $1()]
    +            )
    +            ])],
    +            [AS_VAR_SET([ac_var], [yes])],
    +            [AS_VAR_SET([ac_var], [no])])
    +    ])
    +
    +    AS_IF([test yes = AS_VAR_GET([ac_var])],
    +        [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1), 1,
    +            [Define to 1 if the system has the `$1' built-in function])], [])
    +
    +    AS_VAR_POPDEF([ac_var])
    +])
    
  • Makefile.am+2 5 modified
    @@ -34,10 +34,7 @@ valgrind: all
     		grep "indirectly lost: 0 bytes in 0 blocks" valgrind.log
     
     coveralls:
    -	coveralls -e sixel_orig -e include -e m4 \
    -		-e stb_image.h -e stb_image_write.h
    +	coveralls -e config.h -e stb_image.h -e stb_image_write.h -e examples -e include -e perl -e php -e ruby -e wic
     
     coveralls-dryrun: test
    -	coveralls -e sixel_orig -e include -e m4 \
    -		-e stb_image.h -e stb_image_write.h \
    -		--dryrun
    +	coveralls -e config.h -e stb_image.h -e stb_image_write.h -e examples -e include -e perl -e php -e ruby -e wic --dryrun
    
  • Makefile.in+6 8 modified
    @@ -90,7 +90,8 @@ build_triplet = @build@
     host_triplet = @host@
     subdir = .
     ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
    +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_builtin.m4 \
    +	$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
     	$(top_srcdir)/m4/ax_gcc_var_attribute.m4 \
     	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
     	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
    @@ -192,8 +193,8 @@ CTAGS = ctags
     CSCOPE = cscope
     am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
     	$(srcdir)/libsixel.pc.in $(srcdir)/package.json.in.in \
    -	ChangeLog NEWS compile config.guess config.sub depcomp \
    -	install-sh ltmain.sh missing py-compile
    +	ChangeLog NEWS compile config.guess config.sub install-sh \
    +	ltmain.sh missing py-compile
     DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
     distdir = $(PACKAGE)-$(VERSION)
     top_distdir = $(distdir)
    @@ -930,13 +931,10 @@ valgrind: all
     		grep "indirectly lost: 0 bytes in 0 blocks" valgrind.log
     
     coveralls:
    -	coveralls -e sixel_orig -e include -e m4 \
    -		-e stb_image.h -e stb_image_write.h
    +	coveralls -e config.h -e stb_image.h -e stb_image_write.h -e examples -e include -e perl -e php -e ruby -e wic
     
     coveralls-dryrun: test
    -	coveralls -e sixel_orig -e include -e m4 \
    -		-e stb_image.h -e stb_image_write.h \
    -		--dryrun
    +	coveralls -e config.h -e stb_image.h -e stb_image_write.h -e examples -e include -e perl -e php -e ruby -e wic --dryrun
     
     # Tell versions [3.59,3.63) of GNU make to not export all variables.
     # Otherwise a system limit (for SysV at least) may be exceeded.
    
  • NEWS+24 0 modified
    @@ -2,6 +2,30 @@
                       ------------------------------
                        What's new in libsixel-1.8 ?
                       ------------------------------
    +* Security fix for CVE-2019-20205 (#127), integer overflow problem,
    +  reported by @sleicasper.
    +
    +* Security fix for CVE-2019-20056 (#126), assertion failure problem,
    +  reported by @sleicasper.
    +
    +* Security fix for CVE-2019-20094 (#125), heap overflow problem,
    +  reported by @cuanduo.
    +
    +* Security fix for #124, illegal longjump() call problem,
    +  reported by @cuanduo.
    +
    +* Serucity fix for #74 and #123, access violation problem,
    +  reported by @HongxuChen and SuhwanSong.
    +
    +* Security fix for #122, heap overflow problem,
    +  reported by @SuhwanSong.
    +
    +* Security fix for CVE-2019-20023(#117, #119, #120), memory leaks problem,
    +  reported by @SuhwanSong and @gutiniao.
    +
    +* Strip first flag check in LZW compression function for issue #118,
    +  reported by @yoichi
    +
     * Security fix for CVE-2019-11024 (#85), recursive loop problem,
       reported by @Loginsoft-Research.
     
    
  • package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "libsixel",
    -  "version": "1.8.4",
    +  "version": "1.8.5",
       "repo": "saitoha/libsixel",
       "description": "A lightweight, fast implementation of DEC SIXEL graphics codec",
       "keywords": ["terminal", "graphics", "image", "sixel"],
    
  • python/libsixel/__init__.py+35 20 modified
    @@ -1,6 +1,6 @@
     #!/usr/bin/env python
     #
    -# Copyright (c) 2014-2017 Hayaki Saito
    +# Copyright (c) 2014-2020 Hayaki Saito
     #
     # Permission is hereby granted, free of charge, to any person obtaining a copy of
     # this software and associated documentation files (the "Software"), to deal in
    @@ -23,28 +23,43 @@
     from ctypes import cdll, c_void_p, c_int, c_byte, c_char_p, POINTER, byref, CFUNCTYPE, string_at
     from ctypes.util import find_library
     
    +# limitations
    +SIXEL_OUTPUT_PACKET_SIZE     = 16384
    +SIXEL_PALETTE_MIN            = 2
    +SIXEL_PALETTE_MAX            = 256
    +SIXEL_USE_DEPRECATED_SYMBOLS = 1
    +SIXEL_ALLOCATE_BYTES_MAX     = 10248 * 1024 * 128  # up to 128M
    +SIXEL_WIDTH_LIMIT            = 1000000
    +SIXEL_HEIGHT_LIMIT           = 1000000
    +
    +# loader settings
    +SIXEL_DEFALUT_GIF_DELAY      = 1
    +
    +# return value
     SIXEL_OK              = 0x0000
     SIXEL_FALSE           = 0x1000
     
    -SIXEL_RUNTIME_ERROR   = (SIXEL_FALSE         | 0x0100)  # runtime error
    -SIXEL_LOGIC_ERROR     = (SIXEL_FALSE         | 0x0200)  # logic error
    -SIXEL_FEATURE_ERROR   = (SIXEL_FALSE         | 0x0300)  # feature not enabled
    -SIXEL_LIBC_ERROR      = (SIXEL_FALSE         | 0x0400)  # errors caused by curl
    -SIXEL_CURL_ERROR      = (SIXEL_FALSE         | 0x0500)  # errors occures in libc functions
    -SIXEL_JPEG_ERROR      = (SIXEL_FALSE         | 0x0600)  # errors occures in libjpeg functions
    -SIXEL_PNG_ERROR       = (SIXEL_FALSE         | 0x0700)  # errors occures in libpng functions
    -SIXEL_GDK_ERROR       = (SIXEL_FALSE         | 0x0800)  # errors occures in gdk functions
    -SIXEL_GD_ERROR        = (SIXEL_FALSE         | 0x0900)  # errors occures in gd functions
    -SIXEL_STBI_ERROR      = (SIXEL_FALSE         | 0x0a00)  # errors occures in stb_image functions
    -SIXEL_STBIW_ERROR     = (SIXEL_FALSE         | 0x0b00)  # errors occures in stb_image_write functions
    -
    -SIXEL_INTERRUPTED     = (SIXEL_OK            | 0x0001)  # interrupted by a signal
    -
    -SIXEL_BAD_ALLOCATION  = (SIXEL_RUNTIME_ERROR | 0x0001)  # malloc() failed
    -SIXEL_BAD_ARGUMENT    = (SIXEL_RUNTIME_ERROR | 0x0002)  # bad argument detected
    -SIXEL_BAD_INPUT       = (SIXEL_RUNTIME_ERROR | 0x0003)  # bad input detected
    -
    -SIXEL_NOT_IMPLEMENTED = (SIXEL_FEATURE_ERROR | 0x0001)  # feature not implemented
    +# error codes
    +SIXEL_RUNTIME_ERROR        = (SIXEL_FALSE         | 0x0100)  # runtime error
    +SIXEL_LOGIC_ERROR          = (SIXEL_FALSE         | 0x0200)  # logic error
    +SIXEL_FEATURE_ERROR        = (SIXEL_FALSE         | 0x0300)  # feature not enabled
    +SIXEL_LIBC_ERROR           = (SIXEL_FALSE         | 0x0400)  # errors caused by curl
    +SIXEL_CURL_ERROR           = (SIXEL_FALSE         | 0x0500)  # errors occures in libc functions
    +SIXEL_JPEG_ERROR           = (SIXEL_FALSE         | 0x0600)  # errors occures in libjpeg functions
    +SIXEL_PNG_ERROR            = (SIXEL_FALSE         | 0x0700)  # errors occures in libpng functions
    +SIXEL_GDK_ERROR            = (SIXEL_FALSE         | 0x0800)  # errors occures in gdk functions
    +SIXEL_GD_ERROR             = (SIXEL_FALSE         | 0x0900)  # errors occures in gd functions
    +SIXEL_STBI_ERROR           = (SIXEL_FALSE         | 0x0a00)  # errors occures in stb_image functions
    +SIXEL_STBIW_ERROR          = (SIXEL_FALSE         | 0x0b00)  # errors occures in stb_image_write functions
    +
    +SIXEL_INTERRUPTED          = (SIXEL_OK            | 0x0001)  # interrupted by a signal
    +
    +SIXEL_BAD_ALLOCATION       = (SIXEL_RUNTIME_ERROR | 0x0001)  # malloc() failed
    +SIXEL_BAD_ARGUMENT         = (SIXEL_RUNTIME_ERROR | 0x0002)  # bad argument detected
    +SIXEL_BAD_INPUT            = (SIXEL_RUNTIME_ERROR | 0x0003)  # bad input detected
    +SIXEL_BAD_INTEGER_OVERFLOW = (SIXEL_RUNTIME_ERROR | 0x0004)  /* integer overflow */
    +
    +SIXEL_NOT_IMPLEMENTED      = (SIXEL_FEATURE_ERROR | 0x0001)  # feature not implemented
     
     def SIXEL_SUCCEEDED(status):
         return (((status) & 0x1000) == 0)
    
  • python/Makefile.in+2 1 modified
    @@ -89,7 +89,8 @@ build_triplet = @build@
     host_triplet = @host@
     subdir = python
     ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
    +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_builtin.m4 \
    +	$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
     	$(top_srcdir)/m4/ax_gcc_var_attribute.m4 \
     	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
     	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
    
  • README.md+5 3 modified
    @@ -569,8 +569,8 @@ Options:
                                  rgb:rrrr/gggg/bbbb
     -P, --penetrate            penetrate GNU Screen using DCS
                                pass-through sequence
    --D, --pipe-mode            read source images from stdin
    -                           continuously (deprecated)
    +-D, --pipe-mode            [[deprecated]] read source images from
    +                           stdin continuously
     -v, --verbose              show debugging info
     -V, --version              show version and license info
     -H, --help                 show this help
    @@ -588,6 +588,7 @@ SIXEL_BGCOLOR              specify background color.
                                  rgb:rr/gg/bb
                                  rgb:rrr/ggg/bbb
                                  rgb:rrrr/gggg/bbbb
    +
     ```
     
     Convert a jpeg image file into a sixel file
    @@ -1203,10 +1204,11 @@ Some parts of converters/loader.c are imported from @uobikiemukot's
     
     ### ax_gcc_var_attribute / ax_gcc_func_attribute
     
    -These are useful m4 macros for detecting some GCC attributes.
    +These are useful m4 macros for detecting some GCC attributes / built-in functions.
     
     http://www.gnu.org/software/autoconf-archive/ax_gcc_var_attribute.html
     http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
    +http://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html
     
     > Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
     >
    
  • ruby/LICENSE.txt+1 1 modified
    @@ -1,4 +1,4 @@
    -Copyright (c) 2015 Hayaki Saito
    +Copyright (c) 2015-2018 Hayaki Saito
     
     MIT License
     
    
  • src/allocator.c+35 4 modified
    @@ -19,18 +19,20 @@
      * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      */
     
    -#include <stdlib.h>
    -#include <assert.h>
     #include "config.h"
     
    +#if STDC_HEADERS
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_ASSERT_H
    +# include <assert.h>
    +#endif  /* HAVE_ASSERT_H */
     #if HAVE_SYS_TYPES_H
     # include <sys/types.h>
     #endif  /* HAVE_SYS_TYPES_H */
    -
     #if HAVE_ERRNO_H
     # include <errno.h>
     #endif  /* HAVE_ERRNO_H */
    -
     #if HAVE_MEMORY_H
     # include <memory.h>
     #endif  /* HAVE_MEMORY_H */
    @@ -152,6 +154,11 @@ sixel_allocator_malloc(
                 "sixel_allocator_malloc: called with n == 0");
             return NULL;
         }
    +
    +    if (n > SIXEL_ALLOCATE_BYTES_MAX) {
    +        return NULL;
    +    }
    +
         return allocator->fn_malloc(n);
     }
     
    @@ -163,10 +170,24 @@ sixel_allocator_calloc(
         size_t              /* in */ nelm,        /* number of elements */
         size_t              /* in */ elsize)      /* size of element */
     {
    +    size_t n;
    +
         /* precondition */
         assert(allocator);
         assert(allocator->fn_calloc);
     
    +    n = nelm * elsize;
    +
    +    if (n == 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_allocator_malloc: called with n == 0");
    +        return NULL;
    +    }
    +
    +    if (n > SIXEL_ALLOCATE_BYTES_MAX) {
    +        return NULL;
    +    }
    +
         return allocator->fn_calloc(nelm, elsize);
     }
     
    @@ -182,6 +203,16 @@ sixel_allocator_realloc(
         assert(allocator);
         assert(allocator->fn_realloc);
     
    +    if (n == 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_allocator_malloc: called with n == 0");
    +        return NULL;
    +    }
    +
    +    if (n > SIXEL_ALLOCATE_BYTES_MAX) {
    +        return NULL;
    +    }
    +
         return allocator->fn_realloc(p, n);
     }
     
    
  • src/chunk.c+15 19 modified
    @@ -21,41 +21,37 @@
     
     #include "config.h"
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <string.h>
    -
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
     #if HAVE_SYS_TYPES_H
     # include <sys/types.h>
    -#endif
    -
    +#endif  /* HAVE_SYS_TYPES_H */
     #if HAVE_SYS_STAT_H
     # include <sys/stat.h>
    -#endif
    -
    +#endif  /* HAVE_SYS_STAT_H */
     #if HAVE_UNISTD_H
     # include <unistd.h>
    -#endif
    -
    +#endif  /* HAVE_UNISTD_H */
     #if HAVE_FCNTL_H
     # include <fcntl.h>
    -#endif
    -
    +#endif  /* HAVE_FCNTL_H */
     #if HAVE_IO_H
     # include <io.h>
    -#endif
    -
    +#endif  /* HAVE_IO_H */
     #ifdef HAVE_ERRNO_H
     # include <errno.h>
    -#endif
    -
    +#endif  /* HAVE_ERRNO_H */
     #ifdef HAVE_LIBCURL
     # include <curl/curl.h>
    -#endif
    -
    +#endif  /* HAVE_LIBCURL */
     #if HAVE_SYS_SELECT_H
     # include <sys/select.h>
    -#endif
    +#endif  /* HAVE_SYS_SELECT_H */
     
     #if !defined(HAVE_MEMCPY)
     # define memcpy(d, s, n) (bcopy ((s), (d), (n)))
    
  • src/decoder.c+19 16 modified
    @@ -21,44 +21,47 @@
     
     #include "config.h"
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <stdarg.h>
    -#include <string.h>
    -
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +# include <stdarg.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
     #if HAVE_UNISTD_H
     # include <unistd.h>
    -#endif
    +#endif  /* HAVE_UNISTD_H */
     #if HAVE_SYS_UNISTD_H
     # include <sys/unistd.h>
    -#endif
    +#endif  /* HAVE_UNISTD_H */
     #if HAVE_SYS_TYPES_H
     #include <sys/types.h>
    -#endif
    +#endif  /* HAVE_SYS_TYPES_H */
     #if HAVE_SYS_SELECT_H
     #include <sys/select.h>
    -#endif
    +#endif  /* HAVE_SYS_SELECT_H */
     #if HAVE_TIME_H
     # include <time.h>
    -#endif
    +#endif  /* HAVE_TIME_H */
     #if HAVE_SYS_TIME_H
     # include <sys/time.h>
    -#endif
    +#endif  /* HAVE_SYS_TIME_H */
     #if HAVE_INTTYPES_H
     # include <inttypes.h>
    -#endif
    +#endif  /* HAVE_INTTYPES_H */
     #if HAVE_ERRNO_H
     # include <errno.h>
    -#endif
    +#endif  /* HAVE_ERRNO_H */
     #if HAVE_TERMIOS_H
     # include <termios.h>
    -#endif
    +#endif  /* HAVE_TERMIOS_H */
     #if HAVE_SYS_IOCTL_H
     # include <sys/ioctl.h>
    -#endif
    +#endif  /* HAVE_SYS_IOCTL_H */
     #if HAVE_IO_H
     # include <io.h>
    -#endif
    +#endif  /* HAVE_IO_H */
     
     #include "decoder.h"
     
    
  • src/dither.c+25 14 modified
    @@ -21,18 +21,22 @@
     
     #include "config.h"
     
    -#include <string.h>
    -#include <stdlib.h>
    -#include <stdio.h>
    -#include <math.h>
    -
    +#if STDC_HEADERS
    +# include <stdlib.h>
    +# include <stdio.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_MATH_H
    +# include <math.h>
    +#endif  /* HAVE_MATH_H */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
     #if HAVE_LIMITS_H
     # include <limits.h>
    -#endif
    -
    +#endif  /* HAVE_LIMITS_H */
     #if HAVE_INTTYPES_H
     # include <inttypes.h>
    -#endif
    +#endif  /* HAVE_INTTYPES_H */
     
     #include "dither.h"
     #include "quant.h"
    @@ -262,6 +266,7 @@ sixel_dither_new(
         size_t wholesize;
         int quality_mode;
     
    +    /* ensure given pointer is not null */
         if (ppdither == NULL) {
             sixel_helper_set_additional_message(
                 "sixel_dither_new: ppdither is null.");
    @@ -285,7 +290,7 @@ sixel_dither_new(
         } else {
             if (ncolors > SIXEL_PALETTE_MAX) {
                 status = SIXEL_BAD_INPUT;
    -            ncolors = SIXEL_PALETTE_MAX;
    +            goto end;
             } else if (ncolors < 1) {
                 status = SIXEL_BAD_INPUT;
                 sixel_helper_set_additional_message(
    @@ -523,13 +528,15 @@ sixel_dither_initialize(
         unsigned char *input_pixels;
         SIXELSTATUS status = SIXEL_FALSE;
     
    +    /* ensure dither object is not null */
         if (dither == NULL) {
             sixel_helper_set_additional_message(
                 "sixel_dither_new: dither is null.");
             status = SIXEL_BAD_ARGUMENT;
             goto end;
         }
     
    +    /* increment ref count */
         sixel_dither_ref(dither);
     
         sixel_dither_set_pixelformat(dither, pixelformat);
    @@ -593,7 +600,10 @@ sixel_dither_initialize(
     
     end:
         free(normalized_pixels);
    +
    +    /* decrement ref count */
         sixel_dither_unref(dither);
    +
         return status;
     }
     
    @@ -714,7 +724,7 @@ sixel_dither_set_transparent(
     
     
     /* set transparent */
    -SIXELAPI unsigned char *
    +SIXELAPI sixel_index_t *
     sixel_dither_apply_palette(
         sixel_dither_t  /* in */ *dither,
         unsigned char   /* in */ *pixels,
    @@ -723,11 +733,12 @@ sixel_dither_apply_palette(
     {
         SIXELSTATUS status = SIXEL_FALSE;
         size_t bufsize;
    -    unsigned char *dest = NULL;
    +    sixel_index_t *dest = NULL;
         int ncolors;
         unsigned char *normalized_pixels = NULL;
         unsigned char *input_pixels;
     
    +    /* ensure dither object is not null */
         if (dither == NULL) {
             sixel_helper_set_additional_message(
                 "sixel_dither_apply_palette: dither is null.");
    @@ -737,8 +748,8 @@ sixel_dither_apply_palette(
     
         sixel_dither_ref(dither);
     
    -    bufsize = (size_t)(width * height) * sizeof(unsigned char);
    -    dest = (unsigned char *)sixel_allocator_malloc(dither->allocator, bufsize);
    +    bufsize = (size_t)(width * height) * sizeof(sixel_index_t);
    +    dest = (sixel_index_t *)sixel_allocator_malloc(dither->allocator, bufsize);
         if (dest == NULL) {
             sixel_helper_set_additional_message(
                 "sixel_dither_new: sixel_allocator_malloc() failed.");
    @@ -825,7 +836,7 @@ test1(void)
     #  pragma GCC diagnostic push
     #  pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     #endif
    -    dither = sixel_dither_create(0);
    +    dither = sixel_dither_create(2);
     #if HAVE_DIAGNOSTIC_DEPRECATED_DECLARATIONS
     #  pragma GCC diagnostic pop
     #endif
    
  • src/dither.h+1 1 modified
    @@ -51,7 +51,7 @@ extern "C" {
     #endif
     
     /* apply palette */
    -unsigned char *
    +sixel_index_t *
     sixel_dither_apply_palette(struct sixel_dither /* in */ *dither,
                                unsigned char       /* in */ *pixels,
                                int                 /* in */ width,
    
  • src/encoder.c+26 20 modified
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2014-2018 Hayaki Saito
    + * Copyright (c) 2014-2019 Hayaki Saito
      *
      * Permission is hereby granted, free of charge, to any person obtaining a copy of
      * this software and associated documentation files (the "Software"), to deal in
    @@ -21,38 +21,41 @@
     
     #include "config.h"
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <stdarg.h>
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +# include <stdarg.h>
    +#endif  /* STDC_HEADERS */
    +# if HAVE_STRING_H
     #include <string.h>
    -
    +#endif  /* HAVE_STRING_H */
     #if HAVE_UNISTD_H
     # include <unistd.h>
    -#endif
    +#endif  /* HAVE_UNISTD_H */
     #if HAVE_SYS_UNISTD_H
     # include <sys/unistd.h>
    -#endif
    +#endif  /* HAVE_SYS_UNISTD_H */
     #if HAVE_SYS_TYPES_H
    -#include <sys/types.h>
    -#endif
    +# include <sys/types.h>
    +#endif  /* HAVE_SYS_TYPES_H */
     #if HAVE_TIME_H
     # include <time.h>
    -#endif
    +#endif  /* HAVE_TIME_H */
     #if HAVE_SYS_TIME_H
     # include <sys/time.h>
    -#endif
    +#endif  /* HAVE_SYS_TIME_H */
     #if HAVE_INTTYPES_H
     # include <inttypes.h>
    -#endif
    +#endif  /* HAVE_INTTYPES_H */
     #if HAVE_ERRNO_H
     # include <errno.h>
    -#endif
    +#endif  /* HAVE_ERRNO_H */
     #if HAVE_SYS_STAT_H
     # include <sys/stat.h>
    -#endif
    +#endif  /* HAVE_SYS_STAT_H */
     #if HAVE_FCNTL_H
     # include <fcntl.h>
    -#endif
    +#endif  /* HAVE_FCNTL_H */
     
     #include <sixel.h>
     #include "tty.h"
    @@ -447,7 +450,7 @@ sixel_prepare_specified_palette(
         status = sixel_helper_load_image_file(encoder->mapfile,
                                               1,   /* fstatic */
                                               1,   /* fuse_palette */
    -                                          256, /* reqcolors */
    +                                          SIXEL_PALETTE_MAX, /* reqcolors */
                                               encoder->bgcolor,
                                               SIXEL_LOOP_DISABLE,
                                               load_image_callback_for_palette,
    @@ -568,6 +571,7 @@ sixel_encoder_prepare_palette(
         if (SIXEL_FAILED(status)) {
             goto end;
         }
    +
         status = sixel_dither_initialize(*dither,
                                          sixel_frame_get_pixels(frame),
                                          sixel_frame_get_width(frame),
    @@ -736,7 +740,8 @@ sixel_encoder_output_without_macro(
         SIXELSTATUS status = SIXEL_OK;
         static unsigned char *p;
         int depth;
    -    char message[256];
    +    enum { message_buffer_size = 256 };
    +    char message[message_buffer_size];
         int nwrite;
     #if HAVE_NANOSLEEP
         int dulation;
    @@ -759,7 +764,7 @@ sixel_encoder_output_without_macro(
             status = SIXEL_BAD_ARGUMENT;
             goto end;
         }
    -    
    +
         if (encoder->color_option == SIXEL_COLOR_OPTION_DEFAULT) {
             sixel_dither_set_optimize_palette(dither, 1);
         }
    @@ -837,7 +842,8 @@ sixel_encoder_output_with_macro(
         sixel_encoder_t /* in */ *encoder)
     {
         SIXELSTATUS status = SIXEL_OK;
    -    char buffer[256];
    +    enum { message_buffer_size = 256 };
    +    char buffer[message_buffer_size];
         int nwrite;
     #if HAVE_NANOSLEEP
         int dulation;
    @@ -1164,7 +1170,7 @@ sixel_encoder_new(
         env_default_ncolors = getenv("SIXEL_COLORS");
         if (env_default_ncolors) {
             ncolors = atoi(env_default_ncolors); /* may overflow */
    -        if (ncolors > 1 && ncolors <= 256) {
    +        if (ncolors > 1 && ncolors <= SIXEL_PALETTE_MAX) {
                 (*ppencoder)->reqcolors = ncolors;
             }
         }
    
  • src/frame.c+96 12 modified
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2014-2018 Hayaki Saito
    + * Copyright (c) 2014-2020 Hayaki Saito
      *
      * Permission is hereby granted, free of charge, to any person obtaining a copy of
      * this software and associated documentation files (the "Software"), to deal in
    @@ -21,18 +21,20 @@
     
     #include "config.h"
     
    -#include <string.h>
    -#include <stdlib.h>
    -#include <stdio.h>
    -#include <math.h>
    -
    +#if STDC_HEADERS
    +# include <string.h>
    +# include <stdlib.h>
    +# include <stdio.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_MATH_H
    +# include <math.h>
    +#endif  /* HAVE_MATH_H */
     #if HAVE_LIMITS_H
     # include <limits.h>
    -#endif
    -
    +#endif  /* HAVE_LIMITS_H */
     #if HAVE_INTTYPES_H
     # include <inttypes.h>
    -#endif
    +#endif  /* HAVE_INTTYPES_H */
     
     #include "frame.h"
     
    @@ -150,18 +152,49 @@ sixel_frame_init(
         int             /* in */ ncolors        /* number of palette colors or (-1) */
     )
     {
    +    SIXELSTATUS status = SIXEL_FALSE;
    +
         sixel_frame_ref(frame);
     
    +    /* check parameters */
    +    if (width <= 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_init: an invalid width parameter detected.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (height <= 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_init: an invalid width parameter detected.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (width > SIXEL_WIDTH_LIMIT) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_init: given width parameter is too huge.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (height > SIXEL_HEIGHT_LIMIT) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_init: given height parameter is too huge.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
         frame->pixels = pixels;
         frame->width = width;
         frame->height = height;
         frame->pixelformat = pixelformat;
         frame->palette = palette;
         frame->ncolors = ncolors;
     
    +    status = SIXEL_OK;
    +
    +end:
         sixel_frame_unref(frame);
     
    -    return SIXEL_OK;
    +    return status;
     }
     
     
    @@ -479,7 +512,6 @@ sixel_frame_convert_to_rgb888(sixel_frame_t /*in */ *frame)
         return status;
     }
     
    -
     /* resize a frame to given size with specified resampling filter */
     SIXELAPI SIXELSTATUS
     sixel_frame_resize(
    @@ -495,12 +527,38 @@ sixel_frame_resize(
     
         sixel_frame_ref(frame);
     
    +    /* check parameters */
    +    if (width <= 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_resize: an invalid width parameter detected.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (height <= 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_resize: an invalid width parameter detected.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (width > SIXEL_WIDTH_LIMIT) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_resize: given width parameter is too huge.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (height > SIXEL_HEIGHT_LIMIT) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_resize: given height parameter is too huge.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
         status = sixel_frame_convert_to_rgb888(frame);
         if (SIXEL_FAILED(status)) {
             goto end;
         }
     
    -    size = (size_t)(width * height * 3);
    +    size = (size_t)width * (size_t)height * 3UL;
         scaled_frame = (unsigned char *)sixel_allocator_malloc(frame->allocator, size);
         if (scaled_frame == NULL) {
             sixel_helper_set_additional_message(
    @@ -618,6 +676,32 @@ sixel_frame_clip(
     
         sixel_frame_ref(frame);
     
    +    /* check parameters */
    +    if (width <= 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_clip: an invalid width parameter detected.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (height <= 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_clip: an invalid width parameter detected.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (width > SIXEL_WIDTH_LIMIT) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_clip: given width parameter is too huge.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +    if (height > SIXEL_HEIGHT_LIMIT) {
    +        sixel_helper_set_additional_message(
    +            "sixel_frame_clip: given height parameter is too huge.");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
         switch (frame->pixelformat) {
         case SIXEL_PIXELFORMAT_PAL1:
         case SIXEL_PIXELFORMAT_PAL2:
    
  • src/fromgif.c+54 32 modified
    @@ -26,10 +26,21 @@
      */
     
     #include "config.h"
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <string.h>
    -#include <ctype.h>
    +
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
    +#if HAVE_CTYPE_H
    +# include <ctype.h>
    +#endif  /* HAVE_CTYPE_H */
    +#if HAVE_ASSERT_H
    +# include <assert.h>
    +#endif  /* HAVE_ASSERT_H */
    +
     #include "frame.h"
     #include "fromgif.h"
     
    @@ -179,14 +190,16 @@ gif_init_frame(
         SIXELSTATUS status = SIXEL_OK;
         int i;
         int ncolors;
    +    size_t palette_size, frame_size;
     
         frame->delay = pg->delay;
    -    ncolors = 2 << (pg->flags & 7);
    +    ncolors = 2 << (((pg->lflags & 0x80) ? pg->lflags : pg->flags) & 7);
    +    palette_size = (size_t)ncolors * 3;
         if (frame->palette == NULL) {
    -        frame->palette = (unsigned char *)sixel_allocator_malloc(frame->allocator, (size_t)(ncolors * 3));
    +        frame->palette = (unsigned char *)sixel_allocator_malloc(frame->allocator, palette_size);
         } else if (frame->ncolors < ncolors) {
             sixel_allocator_free(frame->allocator, frame->palette);
    -        frame->palette = (unsigned char *)sixel_allocator_malloc(frame->allocator, (size_t)(ncolors * 3));
    +        frame->palette = (unsigned char *)sixel_allocator_malloc(frame->allocator, palette_size);
         }
         if (frame->palette == NULL) {
             sixel_helper_set_additional_message(
    @@ -198,15 +211,15 @@ gif_init_frame(
         if (frame->ncolors <= reqcolors && fuse_palette) {
             frame->pixelformat = SIXEL_PIXELFORMAT_PAL8;
             sixel_allocator_free(frame->allocator, frame->pixels);
    -        frame->pixels = (unsigned char *)sixel_allocator_malloc(frame->allocator,
    -                                                                (size_t)(frame->width * frame->height));
    +        frame_size = (size_t)frame->width * (size_t)frame->height;
    +        frame->pixels = (unsigned char *)sixel_allocator_malloc(frame->allocator, frame_size);
             if (frame->pixels == NULL) {
                 sixel_helper_set_additional_message(
                     "sixel_allocator_malloc() failed in gif_init_frame().");
                 status = SIXEL_BAD_ALLOCATION;
                 goto end;
             }
    -        memcpy(frame->pixels, pg->out, (size_t)(frame->width * frame->height));
    +        memcpy(frame->pixels, pg->out, frame_size);
     
             for (i = 0; i < frame->ncolors; ++i) {
                 frame->palette[i * 3 + 0] = pg->color_table[i * 3 + 2];
    @@ -236,8 +249,8 @@ gif_init_frame(
             }
         } else {
             frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
    -        frame->pixels = (unsigned char *)sixel_allocator_malloc(frame->allocator,
    -                                                                (size_t)(pg->w * pg->h * 3));
    +        frame_size = (size_t)pg->w * (size_t)pg->h * 3;
    +        frame->pixels = (unsigned char *)sixel_allocator_malloc(frame->allocator, frame_size);
             if (frame->pixels == NULL) {
                 sixel_helper_set_additional_message(
                     "sixel_allocator_malloc() failed in gif_init_frame().");
    @@ -275,7 +288,7 @@ gif_out_code(
             return;
         }
     
    -    g->out[g->cur_x + g->cur_y * g->line_size] = g->codes[code].suffix;
    +    g->out[g->cur_x + g->cur_y * g->max_x] = g->codes[code].suffix;
         if (g->cur_x >= g->actual_width) {
             g->actual_width = g->cur_x + 1;
         }
    @@ -307,7 +320,6 @@ gif_process_raster(
         SIXELSTATUS status = SIXEL_FALSE;
         unsigned char lzw_cs;
         signed int len, code;
    -    unsigned int first;
         signed int codesize, codemask, avail, oldcode, bits, valid_bits, clear;
         gif_lzw *p;
     
    @@ -321,7 +333,6 @@ gif_process_raster(
         }
     
         clear = 1 << lzw_cs;
    -    first = 1;
         codesize = lzw_cs + 1;
         codemask = (1 << codesize) - 1;
         bits = 0;
    @@ -358,20 +369,13 @@ gif_process_raster(
                     codemask = (1 << codesize) - 1;
                     avail = clear + 2;
                     oldcode = -1;
    -                first = 0;
                 } else if (code == clear + 1) { /* end of stream code */
                     s->img_buffer += len;
                     while ((len = gif_get8(s)) > 0) {
                         s->img_buffer += len;
                     }
                     return SIXEL_OK;
                 } else if (code <= avail) {
    -                if (first) {
    -                    sixel_helper_set_additional_message(
    -                        "corrupt GIF (reason: no clear code).");
    -                    status = SIXEL_RUNTIME_ERROR;
    -                    goto end;
    -                }
                     if (oldcode >= 0) {
                         if (avail < (1 << gif_lzw_max_code_size)) {
                             p = &g->codes[avail++];
    @@ -420,20 +424,21 @@ gif_load_next(
     {
         SIXELSTATUS status = SIXEL_FALSE;
         unsigned char buffer[256];
    +    unsigned char c;
         int x;
         int y;
         int w;
         int h;
         int len;
     
         for (;;) {
    -        switch (gif_get8(s)) {
    +        switch ((c = gif_get8(s))) {
             case 0x2C:  /* Image Separator (1 byte) */
                 x = gif_get16le(s);  /* Image Left Position (2 bytes)*/
                 y = gif_get16le(s);  /* Image Top Position (2 bytes) */
                 w = gif_get16le(s);  /* Image Width (2 bytes) */
                 h = gif_get16le(s);  /* Image Height (2 bytes) */
    -            if (((x + w) > (g->w)) || ((y + h) > (g->h))) {
    +            if (x >= g->w || y >= g->h || x + w > g->w || y + h > g->h) {
                     sixel_helper_set_additional_message(
                         "corrupt GIF (reason: bad Image Separator).");
                     status = SIXEL_RUNTIME_ERROR;
    @@ -513,6 +518,10 @@ gif_load_next(
                         g->delay = gif_get16le(s); /* delay */
                         g->transparent = gif_get8(s);
                     } else {
    +                    if (s->img_buffer + len > s->img_buffer_end) {
    +                        status = SIXEL_RUNTIME_ERROR;
    +                        goto end;
    +                    }
                         s->img_buffer += len;
                         break;
                     }
    @@ -544,10 +553,20 @@ gif_load_next(
                     }
                     break;
                 default:
    +                len = gif_get8(s);  /* block size */
    +                if (s->img_buffer + len > s->img_buffer_end) {
    +                    status = SIXEL_RUNTIME_ERROR;
    +                    goto end;
    +                }
    +                memcpy(buffer, s->img_buffer, (size_t)len);
    +                s->img_buffer += len;
                     break;
                 }
    -            while ((len = gif_get8(s)) != 0) {
    -                s->img_buffer += len;
    +            if ((c = gif_get8(s)) != 0x00) {
    +                sprintf((char *)buffer, "missing valid block terminator (unknown code %02x).", c);
    +                sixel_helper_set_additional_message((char *)buffer);
    +                status = SIXEL_RUNTIME_ERROR;
    +                goto end;
                 }
                 break;
     
    @@ -557,8 +576,8 @@ gif_load_next(
                 goto end;
     
             default:
    -            sixel_helper_set_additional_message(
    -                "corrupt GIF (reason: unknown code).");
    +            sprintf((char *)buffer, "corrupt GIF (reason: unknown code %02x).", c);
    +            sixel_helper_set_additional_message((char *)buffer);
                 status = SIXEL_RUNTIME_ERROR;
                 goto end;
             }
    @@ -593,9 +612,9 @@ load_gif(
         SIXELSTATUS status = SIXEL_FALSE;
         sixel_frame_t *frame;
         fn_pointer fnp;
    +    char message[256];
     
         fnp.p = fn_load;
    -    g.out = NULL;
     
         status = sixel_frame_new(&frame, allocator);
         if (SIXEL_FAILED(status)) {
    @@ -604,14 +623,17 @@ load_gif(
         s.img_buffer = s.img_buffer_original = (unsigned char *)buffer;
         s.img_buffer_end = (unsigned char *)buffer + size;
         memset(&g, 0, sizeof(g));
    +    g.delay = SIXEL_DEFALUT_GIF_DELAY;
         status = gif_load_header(&s, &g);
         if (status != SIXEL_OK) {
             goto end;
         }
    -    g.out = (unsigned char *)sixel_allocator_malloc(allocator, (size_t)(g.w * g.h));
    +    g.out = (unsigned char *)sixel_allocator_malloc(allocator, (size_t)g.w * (size_t)g.h);
         if (g.out == NULL) {
    -        sixel_helper_set_additional_message(
    -            "load_gif: sixel_allocator_malloc() failed.");
    +        sprintf(message,
    +                "load_gif: sixel_allocator_malloc() failed. size=%zu.",
    +                (size_t)g.max_x * (size_t)g.max_y);
    +        sixel_helper_set_additional_message(message);
             status = SIXEL_BAD_ALLOCATION;
             goto end;
         }
    
  • src/frompnm.c+17 8 modified
    @@ -20,10 +20,19 @@
      * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      */
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <string.h>
    -#include <ctype.h>
    +#include "config.h"
    +
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
    +#if HAVE_CTYPE_H
    +# include <ctype.h>
    +#endif  /* HAVE_CTYPE_H */
    +
     #include <sixel.h>
     
     #define PNM_MAX_WIDTH  (1 << 16)
    @@ -83,6 +92,7 @@ load_pnm(unsigned char      /* in */  *p,
         unsigned char *s;
         unsigned char *end;
         unsigned char tmp[256];
    +    size_t size;
     
         (void) ppalette;
         (void) pncolors;
    @@ -210,9 +220,8 @@ load_pnm(unsigned char      /* in */  *p,
             goto invalid;
         }
     
    -    *result = (unsigned char *)sixel_allocator_malloc(
    -        allocator,
    -        (size_t)(width * height * 3 + 1));
    +    size = (size_t)width * (size_t)height * 3 + 1;
    +    *result = (unsigned char *)sixel_allocator_malloc(allocator, size);
     
         if (*result == NULL) {
             sixel_helper_set_additional_message(
    @@ -221,7 +230,7 @@ load_pnm(unsigned char      /* in */  *p,
             goto end;
         }
     
    -    memset(*result, 0, (size_t)(width * height * 3 + 1));
    +    (void) memset(*result, 0, size);
     
         for (y = 0 ; y < height ; y++) {
             for (x = 0 ; x < width ; x++) {
    
  • src/fromsixel.c+70 116 modified
    @@ -11,52 +11,26 @@
      * He declares this is compatible with MIT/BSD/GPL.
      *
      * Hayaki Saito <saitoha@me.com> modified this and re-licensed
    - * it under the MIT license.
    - *
    - * The helper function hls_to_rgb is imported from Xterm pl#310.
    - * This is originally written by Ross Combs.
    - * Hayaki Saito <saitoha@me.com> slightly modified this.
    - *
    - * -------------------------------------------------------------------------
    - * Copyright 2013,2014 by Ross Combs
    - *
    - *                         All Rights Reserved
    - *
    - * Permission is hereby granted, free of charge, to any person obtaining a
    - * copy of this software and associated documentation files (the
    - * "Software"), to deal in the Software without restriction, including
    - * without limitation the rights to use, copy, modify, merge, publish,
    - * distribute, sublicense, and/or sell copies of the Software, and to
    - * permit persons to whom the Software is furnished to do so, subject to
    - * the following conditions:
    - *
    - * The above copyright notice and this permission notice shall be included
    - * in all copies or substantial portions of the Software.
    - *
    - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    - * IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
    - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    - *
    - * Except as contained in this notice, the name(s) of the above copyright
    - * holders shall not be used in advertising or otherwise to promote the
    - * sale, use or other dealings in this Software without prior written
    - * authorization.
    - * -------------------------------------------------------------------------
    + * it to the MIT license.
      */
     #include "config.h"
    -#include <stdlib.h>
    -#include <stdio.h>
    -#include <ctype.h>   /* isdigit */
    -#include <string.h>  /* memcpy */
    -#include <limits.h>
     
    -#if defined(HAVE_INTTYPES_H)
    +#if STDC_HEADERS
    +# include <stdlib.h>
    +# include <stdio.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_CTYPE_H
    +# include <ctype.h>   /* isdigit */
    +#endif  /* HAVE_CTYPE_H */
    +#if HAVE_STRING_H
    +# include <string.h>  /* memcpy */
    +#endif  /* HAVE_STRING_H */
    +#if HAVE_LIMITS_H
    +# include <limits.h>
    +#endif  /* HAVE_LIMITS_H */
    +#if HAVE_INTTYPES_H
     # include <inttypes.h>
    -#endif
    +#endif  /* HAVE_INTTYPES_H */
     
     #include <sixel.h>
     #include "output.h"
    @@ -135,83 +109,62 @@ typedef struct parser_context {
     static int
     hls_to_rgb(int hue, int lum, int sat)
     {
    -    double hs = (hue + 240) % 360;
    -    double hv = hs / 360.0;
    -    double lv = lum / 100.0;
    -    double sv = sat / 100.0;
    -    double c, x, m, c2;
    -    double r1, g1, b1;
    +    double min, max;
         int r, g, b;
    -    int hpi;
     
         if (sat == 0) {
    -        r = g = b = lum * 255 / 100;
    -        return SIXEL_RGB(r, g, b);
    +        r = g = b = lum;
         }
     
    -    if ((c2 = ((2.0 * lv) - 1.0)) < 0.0) {
    -        c2 = -c2;
    -    }
    -    c = (1.0 - c2) * sv;
    -    hpi = (int) (hv * 6.0);
    -    x = c * (((hpi & 1) << 1) - 1) * ((hpi + (hpi & 1)) - hs / 60.0);
    -    m = lv - 0.5 * c;
    -
    -    switch (hpi) {
    -    case 0:
    -        r1 = c;
    -        g1 = x;
    -        b1 = 0.0;
    +    /* https://wikimedia.org/api/rest_v1/media/math/render/svg/17e876f7e3260ea7fed73f69e19c71eb715dd09d */
    +    max = lum + sat * (1.0 - (lum > 50 ? (((lum << 2) / 100.0) - 1.0): - (2 * (lum / 100.0) - 1.0))) / 2.0;
    +
    +    /* https://wikimedia.org/api/rest_v1/media/math/render/svg/f6721b57985ad83db3d5b800dc38c9980eedde1d */
    +    min = lum - sat * (1.0 - (lum > 50 ? (((lum << 2) / 100.0) - 1.0): - (2 * (lum / 100.0) - 1.0))) / 2.0;
    +
    +    /* sixel hue color ring is roteted -120 degree from nowdays general one. */
    +    hue = (hue + 240) % 360;
    +
    +    /* https://wikimedia.org/api/rest_v1/media/math/render/svg/937e8abdab308a22ff99de24d645ec9e70f1e384 */
    +    switch (hue / 60) {
    +    case 0:  /* 0 <= hue < 60 */
    +        r = max;
    +        g = (min + (max - min) * (hue / 60.0));
    +        b = min;
             break;
    -    case 1:
    -        r1 = x;
    -        g1 = c;
    -        b1 = 0.0;
    +    case 1:  /* 60 <= hue < 120 */
    +        r = min + (max - min) * ((120 - hue) / 60.0);
    +        g = max;
    +        b = min;
             break;
    -    case 2:
    -        r1 = 0.0;
    -        g1 = c;
    -        b1 = x;
    +    case 2:  /* 120 <= hue < 180 */
    +        r = min;
    +        g = max;
    +        b = (min + (max - min) * ((hue - 120) / 60.0));
             break;
    -    case 3:
    -        r1 = 0.0;
    -        g1 = x;
    -        b1 = c;
    +    case 3:  /* 180 <= hue < 240 */
    +        r = min;
    +        g = (min + (max - min) * ((240 - hue) / 60.0));
    +        b = max;
             break;
    -    case 4:
    -        r1 = x;
    -        g1 = 0.0;
    -        b1 = c;
    +    case 4:  /* 240 <= hue < 300 */
    +        r = (min + (max - min) * ((hue - 240) / 60.0));
    +        g = min;
    +        b = max;
             break;
    -    case 5:
    -        r1 = c;
    -        g1 = 0.0;
    -        b1 = x;
    +    case 5:  /* 300 <= hue < 360 */
    +        r = max;
    +        g = min;
    +        b = (min + (max - min) * ((360 - hue) / 60.0));
             break;
         default:
    -        return SIXEL_RGB(255, 255, 255);
    +#if HAVE___BUILTIN_UNREACHABLE
    +        __builtin_unreachable();
    +#endif
    +        break;
         }
     
    -    r = (int) ((r1 + m) * 100.0 + 0.5);
    -    g = (int) ((g1 + m) * 100.0 + 0.5);
    -    b = (int) ((b1 + m) * 100.0 + 0.5);
    -
    -    if (r < 0) {
    -        r = 0;
    -    } else if (r > 100) {
    -        r = 100;
    -    }
    -    if (g < 0) {
    -        g = 0;
    -    } else if (g > 100) {
    -        g = 100;
    -    }
    -    if (b < 0) {
    -        b = 0;
    -    } else if (b > 100) {
    -        b = 100;
    -    }
    -    return SIXEL_RGB(r * 255 / 100, g * 255 / 100, b * 255 / 100);
    +    return SIXEL_XRGB(r, g, b);
     }
     
     
    @@ -244,12 +197,6 @@ image_buffer_init(
             status = SIXEL_BAD_INPUT;
             goto end;
         }
    -    if (height > SIXEL_HEIGHT_LIMIT) {
    -        sixel_helper_set_additional_message(
    -            "image_buffer_init: given height parameter is too huge.");
    -        status = SIXEL_BAD_INPUT;
    -        goto end;
    -    }
         if (width > SIXEL_WIDTH_LIMIT) {
             sixel_helper_set_additional_message(
                 "image_buffer_init: given width parameter is too huge.");
    @@ -969,31 +916,33 @@ sixel_decode_raw(
         image_buffer_t image;
         int n;
     
    +    image.data = NULL;
    +
         if (allocator) {
             sixel_allocator_ref(allocator);
         } else {
             status = sixel_allocator_new(&allocator, NULL, NULL, NULL, NULL);
             if (SIXEL_FAILED(status)) {
                 allocator = NULL;
    -            goto end;
    +            goto error;
             }
         }
     
         /* parser context initialization */
         status = parser_context_init(&context);
         if (SIXEL_FAILED(status)) {
    -        goto end;
    +        goto error;
         }
     
         /* buffer initialization */
         status = image_buffer_init(&image, 1, 1, context.bgindex, allocator);
         if (SIXEL_FAILED(status)) {
    -        goto end;
    +        goto error;
         }
     
         status = sixel_decode_raw_impl(p, len, &image, &context, allocator);
         if (SIXEL_FAILED(status)) {
    -        goto end;
    +        goto error;
         }
     
         *ncolors = image.ncolors + 1;
    @@ -1008,7 +957,7 @@ sixel_decode_raw(
             sixel_helper_set_additional_message(
                 "sixel_deocde_raw: sixel_allocator_malloc() failed.");
             status = SIXEL_BAD_ALLOCATION;
    -        goto end;
    +        goto error;
         }
         for (n = 0; n < *ncolors; ++n) {
             (*palette)[n * 3 + 0] = image.palette[n] >> 16 & 0xff;
    @@ -1021,6 +970,11 @@ sixel_decode_raw(
         *pixels = image.data;
     
         status = SIXEL_OK;
    +    goto end;
    +
    +error:
    +    free(image.data);
    +    image.data = NULL;
     
     end:
         sixel_allocator_unref(allocator);
    
  • src/loader.c+48 30 modified
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2014-2018 Hayaki Saito
    + * Copyright (c) 2014-2019 Hayaki Saito
      *
      * Permission is hereby granted, free of charge, to any person obtaining a copy of
      * this software and associated documentation files (the "Software"), to deal in
    @@ -21,22 +21,19 @@
     
     #include "config.h"
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <string.h>
    -
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif
     #if HAVE_UNISTD_H
     # include <unistd.h>
     #endif
    -
    -#ifdef HAVE_ERRNO_H
    +#if HAVE_ERRNO_H
     # include <errno.h>
     #endif
    -
    -#if !defined(HAVE_MEMCPY)
    -# define memcpy(d, s, n) (bcopy ((s), (d), (n)))
    -#endif
    -
     #ifdef HAVE_GDK_PIXBUF2
     # if HAVE_DIAGNOSTIC_TYPEDEF_REDEFINITION
     #   pragma GCC diagnostic push
    @@ -47,20 +44,20 @@
     #   pragma GCC diagnostic pop
     # endif
     #endif
    -
    -#ifdef HAVE_GD
    +#if HAVE_GD
     # include <gd.h>
     #endif
    -
    -#ifdef HAVE_LIBPNG
    +#if HAVE_LIBPNG
     # include <png.h>
     #endif  /* HAVE_LIBPNG */
    -
     #if HAVE_JPEG
    -# include <stdio.h>
     # include <jpeglib.h>
     #endif  /* HAVE_JPEG */
     
    +#if !defined(HAVE_MEMCPY)
    +# define memcpy(d, s, n) (bcopy ((s), (d), (n)))
    +#endif
    +
     #include "frame.h"
     #include <sixel.h>
     #include "chunk.h"
    @@ -268,13 +265,18 @@ read_palette(png_structp png_ptr,
         }
     }
     
    +jmp_buf jmpbuf;
     
     /* libpng error handler */
     static void
     png_error_callback(png_structp png_ptr, png_const_charp error_message)
     {
    +    (void) png_ptr;
    +
         sixel_helper_set_additional_message(error_message);
    -    longjmp(png_jmpbuf(png_ptr), (-1));
    +#if HAVE_SETJMP && HAVE_LONGJMP
    +    longjmp(jmpbuf, 1);
    +#endif  /* HAVE_SETJMP && HAVE_LONGJMP */
     }
     
     
    @@ -309,14 +311,14 @@ load_png(unsigned char      /* out */ **result,
         int i;
         int depth;
     
    -#if USE_SETJMP && HAVE_SETJMP
    -    if (setjmp(png_jmpbuf(png_ptr)) != 0) {
    +#if HAVE_SETJMP && HAVE_LONGJMP
    +    if (setjmp(jmpbuf) != 0) {
             sixel_allocator_free(allocator, *result);
             *result = NULL;
             status = SIXEL_PNG_ERROR;
             goto cleanup;
         }
    -#endif  /* HAVE_SETJMP */
    +#endif  /* HAVE_SETJMP && HAVE_LONGJMP */
     
         status = SIXEL_FALSE;
         rows = NULL;
    @@ -330,6 +332,16 @@ load_png(unsigned char      /* out */ **result,
             status = SIXEL_PNG_ERROR;
             goto cleanup;
         }
    +
    +#if HAVE_SETJMP
    +    if (setjmp(png_jmpbuf(png_ptr)) != 0) {
    +        sixel_allocator_free(allocator, *result);
    +        *result = NULL;
    +        status = SIXEL_PNG_ERROR;
    +        goto cleanup;
    +    }
    +#endif  /* HAVE_SETJMP */
    +
         info_ptr = png_create_info_struct(png_ptr);
         if (!info_ptr) {
             sixel_helper_set_additional_message(
    @@ -1331,21 +1343,27 @@ load_with_gd(
     SIXELAPI SIXELSTATUS
     sixel_helper_load_image_file(
         char const                /* in */     *filename,     /* source file name */
    -    int                       /* in */     fstatic,       /* whether to extract static image */
    -    int                       /* in */     fuse_palette,  /* whether to use paletted image */
    -    int                       /* in */     reqcolors,     /* requested number of colors */
    -    unsigned char             /* in */     *bgcolor,      /* background color */
    +    int                       /* in */     fstatic,       /* whether to extract static image from animated gif */
    +    int                       /* in */     fuse_palette,  /* whether to use paletted image, set non-zero value to try to get paletted image */
    +    int                       /* in */     reqcolors,     /* requested number of colors, should be equal or less than SIXEL_PALETTE_MAX */
    +    unsigned char             /* in */     *bgcolor,      /* background color, may be NULL */
         int                       /* in */     loop_control,  /* one of enum loopControl */
         sixel_load_image_function /* in */     fn_load,       /* callback */
         int                       /* in */     finsecure,     /* true if do not verify SSL */
    -    int const                 /* in */     *cancel_flag,  /* cancel flag */
    -    void                      /* in/out */ *context,      /* private data */
    -    sixel_allocator_t         /* in */     *allocator     /* allocator object */
    +    int const                 /* in */     *cancel_flag,  /* cancel flag, may be NULL */
    +    void                      /* in/out */ *context,      /* private data which is passed to callback function as an argument, may be NULL */
    +    sixel_allocator_t         /* in */     *allocator     /* allocator object, may be NULL */
     )
     {
         SIXELSTATUS status = SIXEL_FALSE;
         sixel_chunk_t *pchunk = NULL;
     
    +    /* normalize reqested colors */
    +    if (reqcolors > SIXEL_PALETTE_MAX) {
    +        reqcolors = SIXEL_PALETTE_MAX;
    +    }
    +
    +    /* create new chunk object from file */
         status = sixel_chunk_new(&pchunk, filename, finsecure, cancel_flag, allocator);
         if (status != SIXEL_OK) {
             goto end;
    @@ -1417,7 +1435,7 @@ test1(void)
         unsigned char *ptr = malloc(16);
     
         nret = EXIT_SUCCESS;
    -    goto error; 
    +    goto error;
     
         nret = EXIT_SUCCESS;
     
    
  • src/Makefile.in+2 1 modified
    @@ -92,7 +92,8 @@ host_triplet = @host@
     @COND_TESTS_TRUE@noinst_PROGRAMS = tests$(EXEEXT)
     subdir = src
     ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
    +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_builtin.m4 \
    +	$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
     	$(top_srcdir)/m4/ax_gcc_var_attribute.m4 \
     	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
     	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
    
  • src/malloc_stub.c+6 6 modified
    @@ -19,19 +19,19 @@
      * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      */
     
    -#include <stdlib.h>
     #include "config.h"
     
    +#if STDC_HEADERS
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
     #if HAVE_SYS_TYPES_H
    -#include <sys/types.h>
    +# include <sys/types.h>
     #endif  /* HAVE_SYS_TYPES_H */
    -
     #if HAVE_ERRNO_H
    -#include <errno.h>
    +# include <errno.h>
     #endif  /* HAVE_ERRNO_H */
    -
     #if HAVE_MEMORY_H
    -#include <memory.h>
    +# include <memory.h>
     #endif  /* HAVE_MEMORY_H */
     
     #if !HAVE_MALLOC
    
  • src/output.c+11 5 modified
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2014-2016 Hayaki Saito
    + * Copyright (c) 2014-2019 Hayaki Saito
      *
      * Permission is hereby granted, free of charge, to any person obtaining a copy of
      * this software and associated documentation files (the "Software"), to deal in
    @@ -20,9 +20,15 @@
      */
     
     #include "config.h"
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <assert.h>
    +
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_ASSERT_H
    +# include <assert.h>
    +#endif  /* HAVE_ASSERT_H */
    +
     #include <sixel.h>
     #include "output.h"
     
    @@ -97,7 +103,7 @@ sixel_output_create(sixel_write_function fn_write, void *priv)
         return output;
     }
     
    - 
    +
     /* destroy output context object */
     SIXELAPI void
     sixel_output_destroy(sixel_output_t *output)
    
  • src/output.h+1 1 modified
    @@ -27,7 +27,7 @@ typedef struct sixel_node {
         int pal;
         int sx;
         int mx;
    -    unsigned char *map;
    +    char *map;
     } sixel_node_t;
     
     struct sixel_output {
    
  • src/pixelformat.c+18 14 modified
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2014-2018 Hayaki Saito
    + * Copyright (c) 2014-2019 Hayaki Saito
      *
      * Permission is hereby granted, free of charge, to any person obtaining a copy of
      * this software and associated documentation files (the "Software"), to deal in
    @@ -21,9 +21,13 @@
     
     #include "config.h"
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <memory.h>
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_MEMORY_H
    +# include <memory.h>
    +#endif  /* HAVE_MEMORY_H */
     
     #include <sixel.h>
     
    @@ -333,7 +337,7 @@ test1(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_RGB888;
         unsigned char src[] = { 0x46, 0xf3, 0xe5 };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -367,7 +371,7 @@ test2(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_RGB555;
         unsigned char src[] = { 0x47, 0x9c };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -401,7 +405,7 @@ test3(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_RGB565;
         unsigned char src[] = { 0x47, 0x9c };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -435,7 +439,7 @@ test4(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_BGR888;
         unsigned char src[] = { 0x46, 0xf3, 0xe5 };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -469,7 +473,7 @@ test5(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_BGR555;
         unsigned char src[] = { 0x23, 0xc8 };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -503,7 +507,7 @@ test6(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_BGR565;
         unsigned char src[] = { 0x47, 0x88 };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -537,7 +541,7 @@ test7(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_AG88;
         unsigned char src[] = { 0x47, 0x88 };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -571,7 +575,7 @@ test8(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_GA88;
         unsigned char src[] = { 0x47, 0x88 };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -605,7 +609,7 @@ test9(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_RGBA8888;
         unsigned char src[] = { 0x46, 0xf3, 0xe5, 0xf0 };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    @@ -645,7 +649,7 @@ test10(void)
         int src_pixelformat = SIXEL_PIXELFORMAT_ARGB8888;
         unsigned char src[] = { 0x46, 0xf3, 0xe5, 0xf0 };
         int ret = 0;
    -    
    +
         int nret = EXIT_FAILURE;
     
         ret = sixel_helper_normalize_pixelformat(dst,
    
  • src/quant.c+18 12 modified
    @@ -46,18 +46,22 @@
     
     #include "config.h"
     
    -#include <string.h>
    -#include <stdlib.h>
    -#include <stdio.h>
    +#if STDC_HEADERS
    +# include <stdlib.h>
    +# include <stdio.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
    +#if HAVE_MATH_H
     #include <math.h>
    -
    +#endif  /* HAVE_MATH_H */
     #if HAVE_LIMITS_H
     # include <limits.h>
    -#endif
    -
    +#endif  /* HAVE_MATH_H */
     #if HAVE_INTTYPES_H
     # include <inttypes.h>
    -#endif
    +#endif  /* HAVE_MATH_H */
     
     #include "quant.h"
     
    @@ -138,7 +142,8 @@ alloctupletable(
         sixel_allocator_t   /* in */  *allocator)
     {
         SIXELSTATUS status = SIXEL_FALSE;
    -    char message[256];
    +    enum { message_buffer_size = 256 };
    +    char message[message_buffer_size];
         int nwrite;
         unsigned int mainTableSize;
         unsigned int tupleIntSize;
    @@ -748,6 +753,7 @@ computeHistogram(unsigned char const    /* in */  *data,
         }
     
         colorfreqtableP->size = (unsigned int)(ref - refmap);
    +
         status = alloctupletable(&colorfreqtableP->table, depth, (unsigned int)(ref - refmap), allocator);
         if (SIXEL_FAILED(status)) {
             goto end;
    @@ -1240,7 +1246,7 @@ sixel_quant_make_palette(
     /* apply color palette into specified pixel buffers */
     SIXELSTATUS
     sixel_quant_apply_palette(
    -    unsigned char     /* out */ *result,
    +    sixel_index_t     /* out */ *result,
         unsigned char     /* in */  *data,
         int               /* in */  width,
         int               /* in */  height,
    @@ -1262,8 +1268,8 @@ sixel_quant_apply_palette(
         component_t offset;
         int color_index;
         unsigned short *indextable;
    -    unsigned char new_palette[256 * max_depth];
    -    unsigned short migration_map[256];
    +    unsigned char new_palette[SIXEL_PALETTE_MAX * 4];
    +    unsigned short migration_map[SIXEL_PALETTE_MAX];
         float (*f_mask) (int x, int y, int c) = NULL;
         void (*f_diffuse)(unsigned char *data, int width, int height,
                           int x, int y, int depth, int offset);
    @@ -1360,7 +1366,7 @@ sixel_quant_apply_palette(
         if (foptimize_palette) {
             *ncolors = 0;
     
    -        memset(new_palette, 0x00, sizeof(256 * depth));
    +        memset(new_palette, 0x00, sizeof(SIXEL_PALETTE_MAX * depth));
             memset(migration_map, 0x00, sizeof(migration_map));
     
             if (f_mask) {
    
  • src/quant.h+1 1 modified
    @@ -47,7 +47,7 @@ sixel_quant_make_palette(
     /* apply color palette into specified pixel buffers */
     SIXELSTATUS
     sixel_quant_apply_palette(
    -    unsigned char       /* out */ *result,
    +    sixel_index_t       /* out */ *result,
         unsigned char       /* in */  *data,
         int                 /* in */  width,
         int                 /* in */  height,
    
  • src/scale.c+7 4 modified
    @@ -21,14 +21,17 @@
     
     #include "config.h"
     
    -#define _USE_MATH_DEFINES  /* for MSVC */
    -#include <math.h>
    +#if STDC_HEADERS
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_MATH_H
    +# define _USE_MATH_DEFINES  /* for MSVC */
    +# include <math.h>
    +#endif  /* HAVE_MATH_H */
     #ifndef M_PI
     # define M_PI 3.14159265358979323846
     #endif
     
    -#include <stdlib.h>
    -
     #include <sixel.h>
     
     #if !defined(MAX)
    
  • src/status.c+28 26 modified
    @@ -21,42 +21,44 @@
     
     #include "config.h"
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <memory.h>
    -
    -#include <sixel.h>
    -
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_MEMORY_H
    +# include <memory.h>
    +#endif  /* HAVE_MEMORY_H */
     #ifdef HAVE_STRING_H
     # include <string.h>
    -#endif
    +#endif  /* HAVE_STRING_H */
     #ifdef HAVE_ERRNO_H
     # include <errno.h>
    -#endif
    +#endif  /* HAVE_ERRNO_H */
     #ifdef HAVE_LIBCURL
     # include <curl/curl.h>
    -#endif
    +#endif  /* HAVE_LIBCURL */
     
    +#include <sixel.h>
     #include "status.h"
     
    -#define SIXEL_MESSAGE_OK                ("succeeded")
    -#define SIXEL_MESSAGE_FALSE             ("unexpected error (SIXEL_FALSE)");
    -#define SIXEL_MESSAGE_UNEXPECTED        ("unexpected error")
    -#define SIXEL_MESSAGE_INTERRUPTED       ("interrupted by a signal")
    -#define SIXEL_MESSAGE_BAD_ALLOCATION    ("runtime error: bad allocation error")
    -#define SIXEL_MESSAGE_BAD_ARGUMENT      ("runtime error: bad argument detected")
    -#define SIXEL_MESSAGE_BAD_INPUT         ("runtime error: bad input detected")
    +#define SIXEL_MESSAGE_OK                    ("succeeded")
    +#define SIXEL_MESSAGE_FALSE                 ("unexpected error (SIXEL_FALSE)");
    +#define SIXEL_MESSAGE_UNEXPECTED            ("unexpected error")
    +#define SIXEL_MESSAGE_INTERRUPTED           ("interrupted by a signal")
    +#define SIXEL_MESSAGE_BAD_ALLOCATION        ("runtime error: bad allocation error")
    +#define SIXEL_MESSAGE_BAD_ARGUMENT          ("runtime error: bad argument detected")
    +#define SIXEL_MESSAGE_BAD_INPUT             ("runtime error: bad input detected")
     #define SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW  ("runtime error: integer overflow")
    -#define SIXEL_MESSAGE_RUNTIME_ERROR     ("runtime error")
    -#define SIXEL_MESSAGE_LOGIC_ERROR       ("logic error")
    -#define SIXEL_MESSAGE_NOT_IMPLEMENTED   ("feature error: not implemented")
    -#define SIXEL_MESSAGE_FEATURE_ERROR     ("feature error")
    -#define SIXEL_MESSAGE_STBI_ERROR        ("stb_image error")
    -#define SIXEL_MESSAGE_STBIW_ERROR       ("stb_image_write error")
    -#define SIXEL_MESSAGE_JPEG_ERROR        ("libjpeg error")
    -#define SIXEL_MESSAGE_PNG_ERROR         ("libpng error")
    -#define SIXEL_MESSAGE_GDK_ERROR         ("GDK error")
    -#define SIXEL_MESSAGE_GD_ERROR          ("GD error")
    +#define SIXEL_MESSAGE_RUNTIME_ERROR         ("runtime error")
    +#define SIXEL_MESSAGE_LOGIC_ERROR           ("logic error")
    +#define SIXEL_MESSAGE_NOT_IMPLEMENTED       ("feature error: not implemented")
    +#define SIXEL_MESSAGE_FEATURE_ERROR         ("feature error")
    +#define SIXEL_MESSAGE_STBI_ERROR            ("stb_image error")
    +#define SIXEL_MESSAGE_STBIW_ERROR           ("stb_image_write error")
    +#define SIXEL_MESSAGE_JPEG_ERROR            ("libjpeg error")
    +#define SIXEL_MESSAGE_PNG_ERROR             ("libpng error")
    +#define SIXEL_MESSAGE_GDK_ERROR             ("GDK error")
    +#define SIXEL_MESSAGE_GD_ERROR              ("GD error")
     
     
     static char g_buffer[1024] = { 0x0 };
    
  • src/stb_image.h+20 7 modified
    @@ -507,7 +507,9 @@ STBIDEF int   stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
     
     
     #include <stdarg.h>
    +#if HAVE_STDDEF_H
     #include <stddef.h> // ptrdiff_t on osx
    +#endif  /* HAVE_STDDEF_H */
     #include <stdlib.h>
     #include <string.h>
     #include <limits.h>
    @@ -543,7 +545,9 @@ typedef   signed short stbi__int16;
     typedef unsigned int   stbi__uint32;
     typedef   signed int   stbi__int32;
     #else
    -#include <stdint.h>
    +#if HAVE_STDINT_H
    +# include <stdint.h>
    +#endif
     typedef uint16_t stbi__uint16;
     typedef int16_t  stbi__int16;
     typedef uint32_t stbi__uint32;
    @@ -1497,7 +1501,7 @@ static int stbi__get16le(stbi__context *s)
     static stbi__uint32 stbi__get32le(stbi__context *s)
     {
        stbi__uint32 z = stbi__get16le(s);
    -   return z + (stbi__get16le(s) << 16);
    +   return z + ((stbi__uint32)stbi__get16le(s) << 16);
     }
     #endif
     
    @@ -5045,13 +5049,13 @@ static int stbi__shiftsigned(int v, int shift, int bits)
        static unsigned int shift_table[9] = {
           0, 0,0,1,0,2,4,6,0,
        };
    +   if (bits < 0 || bits > 8) return (0);  /* error */
        if (shift < 0)
           v <<= -shift;
        else
           v >>= shift;
    -   STBI_ASSERT(v >= 0 && v < 256);
    +   if (v < 0 || v >= 256) return (0);
        v >>= (8-bits);
    -   if (bits < 0 || bits > 8) return (0);  /* error */
        return (int) ((unsigned) v * mul_table[bits]) >> shift_table[bits];
     }
     
    @@ -5844,19 +5848,28 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
                 if (ri->bits_per_channel == 16) {    // output bpc
                    stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
                    for (i = 0; i < pixelCount; i++, q += 4) {
    -                  if (stbi__at_eof(s))   return stbi__errpuc("bad file","PSD file too short");
    +                  if (stbi__at_eof(s)) {
    +                     STBI_FREE(out);
    +                     return stbi__errpuc("bad file","PSD file too short");
    +                  }
                       *q = (stbi__uint16) stbi__get16be(s);
                    }
                 } else {
                    stbi_uc *p = out+channel;
                    if (bitdepth == 16) {  // input bpc
                       for (i = 0; i < pixelCount; i++, p += 4) {
    -                     if (stbi__at_eof(s))   return stbi__errpuc("bad file","PSD file too short");
    +                     if (stbi__at_eof(s)) {
    +                        STBI_FREE(out);
    +                        return stbi__errpuc("bad file","PSD file too short");
    +                     }
                          *p = (stbi_uc) (stbi__get16be(s) >> 8);
                       }
                    } else {
                       for (i = 0; i < pixelCount; i++, p += 4) {
    -                     if (stbi__at_eof(s))   return stbi__errpuc("bad file","PSD file too short");
    +                     if (stbi__at_eof(s)) {
    +                        STBI_FREE(out);
    +                        return stbi__errpuc("bad file","PSD file too short");
    +                     }
                          *p = stbi__get8(s);
                       }
                    }
    
  • src/tests.c+14 7 modified
    @@ -21,15 +21,22 @@
     
     #include "config.h"
     
    -#include <string.h>
    -#include <stdlib.h>
    -#include <stdio.h>
    -#include <math.h>
    -#include <limits.h>
    -
    +#if STDC_HEADERS
    +# include <stdlib.h>
    +# include <stdio.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_STDRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
    +#if HAVE_MATH_H
    +# include <math.h>
    +#endif  /* HAVE_MATH_H */
    +#if HAVE_LIMITS_H
    +# include <limits.h>
    +#endif  /* HAVE_LIMITS_H */
     #if HAVE_INTTYPES_H
     # include <inttypes.h>
    -#endif
    +#endif  /* HAVE_INTTYPES_H */
     
     #include <sixel.h>
     #include "dither.h"
    
  • src/tosixel.c+46 22 modified
    @@ -18,14 +18,20 @@
      *
      */
     #include "config.h"
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <string.h>
    -#include <limits.h>
     
    -#if defined(HAVE_INTTYPES_H)
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* HAVE_STDLIB_H */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
    +#if HAVE_LIMITS_H
    +# include <limits.h>
    +#endif  /* HAVE_LIMITS_H */
    +#if HAVE_INTTYPES_H
     # include <inttypes.h>
    -#endif
    +#endif  /* HAVE_INTTYPES_H */
     
     #include <sixel.h>
     #include "output.h"
    @@ -442,9 +448,9 @@ output_hls_palette_definition(
                 h = s = 0;
             } else {
                 if (l < 50) {
    -                s = ((max - min) * 100 + 127) / (max + min);
    +                s = ((max - min) * 100) / (max + min);
                 } else {
    -                s = ((max - min) * 100 + 127) / ((255 - max) + (255 - min));
    +                s = ((max - min) * 100) / ((255 - max) + (255 - min));
                 }
                 if (r == max) {
                     h = 120 + (g - b) * 60 / (max - min);
    @@ -482,7 +488,7 @@ output_hls_palette_definition(
     
     static SIXELSTATUS
     sixel_encode_body(
    -    unsigned char       /* in */ *pixels,
    +    sixel_index_t       /* in */ *pixels,
         int                 /* in */ width,
         int                 /* in */ height,
         unsigned char       /* in */ *palette,
    @@ -503,8 +509,8 @@ sixel_encode_body(
         int mx;
         int len;
         int pix;
    +    char *map = NULL;
         int check_integer_overflow;
    -    unsigned char *map = NULL;
         sixel_node_t *np, *tp, top;
         int fillable;
     
    @@ -515,9 +521,9 @@ sixel_encode_body(
         len = ncolors * width;
         output->active_palette = (-1);
     
    -    map = (unsigned char *)sixel_allocator_calloc(allocator,
    -                                                  (size_t)len,
    -                                                  sizeof(unsigned char));
    +    map = (char *)sixel_allocator_calloc(allocator,
    +                                         (size_t)len,
    +                                         sizeof(char));
         if (map == NULL) {
             sixel_helper_set_additional_message(
                 "sixel_encode_body: sixel_allocator_calloc() failed.");
    @@ -784,8 +790,9 @@ sixel_encode_dither(
         sixel_output_t  /* in */ *output)   /* output context */
     {
         SIXELSTATUS status = SIXEL_FALSE;
    -    unsigned char *paletted_pixels = NULL;
    -    unsigned char *input_pixels;
    +    sixel_index_t *paletted_pixels = NULL;
    +    sixel_index_t *input_pixels;
    +    size_t bufsize;
     
         switch (dither->pixelformat) {
         case SIXEL_PIXELFORMAT_PAL1:
    @@ -794,8 +801,8 @@ sixel_encode_dither(
         case SIXEL_PIXELFORMAT_G1:
         case SIXEL_PIXELFORMAT_G2:
         case SIXEL_PIXELFORMAT_G4:
    -        paletted_pixels = (unsigned char *)sixel_allocator_malloc(dither->allocator,
    -                                                                  (size_t)(width * height * 3));
    +        bufsize = (sizeof(sixel_index_t) * (size_t)width * (size_t)height * 3UL);
    +        paletted_pixels = (sixel_index_t *)sixel_allocator_malloc(dither->allocator, bufsize);
             if (paletted_pixels == NULL) {
                 sixel_helper_set_additional_message(
                     "sixel_encode_dither: sixel_allocator_malloc() failed.");
    @@ -1300,14 +1307,14 @@ sixel_encode_highcolor(
             )
     {
         SIXELSTATUS status = SIXEL_FALSE;
    -    unsigned char *paletted_pixels = NULL;
    +    sixel_index_t *paletted_pixels = NULL;
         unsigned char *normalized_pixels = NULL;
         /* Mark sixel line pixels which have been already drawn. */
         unsigned char *marks;
         unsigned char *rgbhit;
         unsigned char *rgb2pal;
    -    unsigned char palhitcount[256];
    -    unsigned char palstate[256];
    +    unsigned char palhitcount[SIXEL_PALETTE_MAX];
    +    unsigned char palstate[SIXEL_PALETTE_MAX];
         int output_count;
         int const maxcolors = 1 << 15;
         int whole_size = width * height  /* for paletted_pixels */
    @@ -1342,7 +1349,7 @@ sixel_encode_highcolor(
             }
             pixels = normalized_pixels;
         }
    -    paletted_pixels = (unsigned char *)sixel_allocator_malloc(dither->allocator,
    +    paletted_pixels = (sixel_index_t *)sixel_allocator_malloc(dither->allocator,
                                                                   (size_t)whole_size);
         if (paletted_pixels == NULL) {
             goto error;
    @@ -1515,11 +1522,27 @@ sixel_encode(
     {
         SIXELSTATUS status = SIXEL_FALSE;
     
    +    (void) depth;
    +
         /* TODO: reference counting should be thread-safe */
         sixel_dither_ref(dither);
         sixel_output_ref(output);
     
    -    (void) depth;
    +    if (width < 1) {
    +        sixel_helper_set_additional_message(
    +            "sixel_encode: bad width parameter."
    +            " (width < 1)");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
    +    if (height < 1) {
    +        sixel_helper_set_additional_message(
    +            "sixel_encode: bad height parameter."
    +            " (height < 1)");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
     
         if (dither->quality_mode == SIXEL_QUALITY_HIGHCOLOR) {
             status = sixel_encode_highcolor(pixels, width, height,
    @@ -1529,6 +1552,7 @@ sixel_encode(
                                          dither, output);
         }
     
    +end:
         sixel_output_unref(output);
         sixel_dither_unref(dither);
     
    
  • src/tty.c+15 12 modified
    @@ -21,34 +21,37 @@
     
     #include "config.h"
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <string.h>
    -
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* HAVE_STDLIB_H */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
     #if HAVE_SYS_TIME_H
     # include <sys/time.h>
    -#endif
    +#endif  /* HAVE_SYS_TIME_H */
     #if HAVE_SYS_TYPES_H
     # include <sys/types.h>
    -#endif
    +#endif  /* HAVE_SYS_TYPES_H */
     #if HAVE_UNISTD_H
     # include <unistd.h>
    -#endif
    +#endif  /* HAVE_UNISTD_H */
     #if HAVE_SYS_UNISTD_H
     # include <sys/unistd.h>
    -#endif
    +#endif  /* HAVE_SYS_UNISTD_H */
     #if HAVE_SYS_SELECT_H
     # include <sys/select.h>
    -#endif
    +#endif  /* HAVE_SYS_SELECT_H */
     #if HAVE_ERRNO_H
     # include <errno.h>
    -#endif
    +#endif  /* HAVE_ERRNO_H */
     #if HAVE_TERMIOS_H
     # include <termios.h>
    -#endif
    +#endif  /* HAVE_TERMIOS_H */
     #if HAVE_SYS_IOCTL_H
     # include <sys/ioctl.h>
    -#endif
    +#endif  /* HAVE_SYS_IOCTL_H */
     
     #include <sixel.h>
     
    
  • src/writer.c+50 9 modified
    @@ -21,23 +21,24 @@
     
     #include "config.h"
     
    -#include <stdio.h>
    -#include <stdlib.h>
    -#include <string.h>
    -
    +#if STDC_HEADERS
    +# include <stdio.h>
    +# include <stdlib.h>
    +#endif  /* STDC_HEADERS */
    +#if HAVE_STRING_H
    +# include <string.h>
    +#endif  /* HAVE_STRING_H */
     #if HAVE_SETJMP_H
     # include <setjmp.h>
    -#endif
    -
    +#endif  /* HAVE_SETJMP_H */
     #if HAVE_ERRNO_H
     # include <errno.h>
    -#endif
    -
    +#endif  /* HAVE_ERRNO_H */
     #if HAVE_LIBPNG
     # include <png.h>
     #else
     # include "stb_image_write.h"
    -#endif
    +#endif  /* HAVE_LIBPNG */
     
     #include <sixel.h>
     
    @@ -317,6 +318,46 @@ sixel_helper_write_image_file(
             sixel_allocator_ref(allocator);
         }
     
    +    if (width > SIXEL_WIDTH_LIMIT) {
    +        sixel_helper_set_additional_message(
    +            "sixel_encode: bad width parameter."
    +            " (width > SIXEL_WIDTH_LIMIT)");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
    +    if (width > SIXEL_HEIGHT_LIMIT) {
    +        sixel_helper_set_additional_message(
    +            "sixel_encode: bad width parameter."
    +            " (width > SIXEL_HEIGHT_LIMIT)");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
    +    if (height < 1) {
    +        sixel_helper_set_additional_message(
    +            "sixel_encode: bad height parameter."
    +            " (height < 1)");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
    +    if (width < 1) {
    +        sixel_helper_set_additional_message(
    +            "sixel_encode: bad width parameter."
    +            " (width < 1)");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
    +    if (height < 1) {
    +        sixel_helper_set_additional_message(
    +            "sixel_encode: bad height parameter."
    +            " (height < 1)");
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
         switch (imageformat) {
         case SIXEL_FORMAT_PNG:
             status = write_png_to_file(data, width, height, palette,
    
  • tools/Makefile.in+2 1 modified
    @@ -90,7 +90,8 @@ build_triplet = @build@
     host_triplet = @host@
     subdir = tools
     ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    -am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
    +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_gcc_builtin.m4 \
    +	$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \
     	$(top_srcdir)/m4/ax_gcc_var_attribute.m4 \
     	$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
     	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
    
  • .travis.yml+2 2 modified
    @@ -49,8 +49,8 @@ matrix:
     #    env: XCC=clang HOST= PREFIX=/usr/local DEBUG="--enable-tests --enable-debug" WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" LIBCURL="--with-libcurl" JPEG=--without-jpeg PNG=--without-png
       - os: linux
         env: XCC=gcc HOST= PREFIX=/usr DEBUG="--enable-tests --enable-debug" WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" JPEG="--with-jpeg" PNG="--with-png" LIBCURL="--with-libcurl"
    -  - os: osx
    -    env: XCC=gcc HOST= PREFIX=/usr/local DEBUG="--enable-tests --enable-debug" WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" JPEG="--with-jpeg" PNG="--with-png" LIBCURL="--with-libcurl"
    +#  - os: osx
    +#    env: XCC=gcc HOST= PREFIX=/usr/local DEBUG="--enable-tests --enable-debug" WINE= GDKPIXBUF="--with-gdk-pixbuf2" GD="--with-gd" JPEG="--with-jpeg" PNG="--with-png" LIBCURL="--with-libcurl"
       - os: linux
         env: XCC=clang HOST= PREFIX=/usr DEBUG="--enable-tests --enable-debug" WINE= JPEG="--with-jpeg" PNG="--with-png" LIBCURL="--with-libcurl" GCOV="--enable-gcov" STATIC="--disable-shared"
     
    
9d9d1863f5c9

Merge branch 'release'

https://github.com/saitoha/libsixelHayaki SaitoDec 14, 2019via osv
18 files changed · +474 55
  • ChangeLog+183 0 modified
    @@ -1,3 +1,186 @@
    +2019-12-13  Hayaki Saito <saitoha@me.com>
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * src/loader.c: Suppress glib deprecated warnings
    +
    +  * .travis.yml: Ammend fix for e18ebe6
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +  * .travis.yml: Drop mingw32 build
    +
    +2019-12-02  pwd <weidangpeng@gmail.com>
    +
    +  * src/fromsixel.c: use function safe_addition_for_params to check integer
    +  overflow
    +
    +  * src/frompnm.c: fix issue that the width and the deps miss checks
    +
    +  * include/sixel.h.in, src/status.c: define macro SIXEL_BAD_INTEGER_OVERFLOW
    +  for integer
    +
    +  * src/tosixel.c: check integer overflow in 'map[pix * width + x] |= (1 <<
    +  i);'
    +
    +2019-08-29  Takatsugu Nokubi <takatsugu.nokubi@robotfund.co.jp>
    +
    +  * src/loader.c: check jpeg decoder error
    +
    +  * src/fromsixel.c: check size, fix issue #83
    +
    +2019-08-01  Takatsugu Nokubi <takatsugu.nokubi@robotfund.co.jp>
    +
    +  * include/sixel.h.in, src/decoder.c: add limitation to width and height
    +
    +2019-07-25  Takatsugu Nokubi <takatsugu.nokubi@robotfund.co.jp>
    +
    +  * src/fromsixel.c: position error check
    +
    +2019-07-24  Takatsugu Nokubi <takatsugu.nokubi@robotfund.co.jp>
    +
    +  * src/fromsixel.c: prevent to access heap overflow
    +
    +2019-07-23  Takatsugu Nokubi <takatsugu.nokubi@robotfund.co.jp>
    +
    +  * src/stb_image.h: assign default error message
    +
    +2019-07-08  Takatsugu Nokubi <takatsugu.nokubi@robotfund.co.jp>
    +
    +  * src/allocator.c: Add malloc size check
    +
    +  * src/fromsixel.c: size check
    +
    +2019-07-07  Takatsugu Nokubi <takatsugu.nokubi@robotfund.co.jp>
    +
    +  * src/status.c: no op when message is NULL
    +
    +2018-08-06  Hayaki Saito <saitoha@me.com>
    +
    +  * src/stb_image.h: stb_image: fix for #76 POC h050. detect bad PSD file.
    +
    +2018-08-05  Hayaki Saito <saitoha@me.com>
    +
    +  * src/stb_image.h: stb_image: fix for #76 POC h010. detect bad PSD file
    +  which has fake size declaration in its image header
    +
    +  * src/stb_image.h: stb_image: fix for #76 POC h002. detect bad TGA file
    +  which has fake size declaration in its image header
    +
    +  * src/fromgif.c: GIF loader: fix for #76 POC h001. don't believe image size
    +  declared in the header, use actual size.
    +  https://github.com/saitoha/libsixel/issues/76
    +
    +2018-08-03  Hayaki Saito <saitoha@me.com>
    +
    +  * src/stb_image.h: Quickfix for issue #72: validate huffman code
    +  https://github.com/saitoha/libsixel/issues/72
    +
    +2018-08-02  Hayaki Saito <saitoha@me.com>
    +
    +  * src/fromgif.c: gif loader: add some comments
    +
    +  * src/fromgif.c: gif loader: check LZW code size (Issue #75)
    +
    +2018-07-23  Hayaki Saito <saitoha@me.com>
    +
    +  * src/Makefile.am, src/Makefile.in: Amend travis build fixes again
    +
    +  * src/Makefile.am, src/Makefile.in: Amend fix for travis build
    +
    +  * src/Makefile.am, src/Makefile.in: Travis build fixes
    +
    +  * NEWS: Update NEWS
    +
    +  * README.md: Update README.md
    +
    +  * README.md: Update README.md
    +
    +  * README.md: Update README.md
    +
    +  * Makefile.in, README.md, aclocal.m4, compile, config.guess, config.sub,
    +  configure, configure.ac, converters/Makefile.in, depcomp,
    +  include/Makefile.in, install-sh, missing, package.json, py-compile,
    +  python/Makefile.in, src/Makefile.in, tools/Makefile.in: Bump version 1.8.2
    +
    +  * NEWS: Update NEWS
    +
    +  * ChangeLog: Update ChangeLog
    +
     2018-06-10  Hayaki Saito <saitoha@me.com>
     
       * converters/img2sixel.1: Fix a typo: a_dither -> x_dither(issue #66)
    
  • configure+10 10 modified
    @@ -1,6 +1,6 @@
     #! /bin/sh
     # Guess values for system-dependent variables and create Makefiles.
    -# Generated by GNU Autoconf 2.69 for sixel 1.8.2.
    +# Generated by GNU Autoconf 2.69 for sixel 1.8.3.
     #
     # Report bugs to <saitoha@me.com>.
     #
    @@ -590,8 +590,8 @@ MAKEFLAGS=
     # Identity of this package.
     PACKAGE_NAME='sixel'
     PACKAGE_TARNAME='sixel'
    -PACKAGE_VERSION='1.8.2'
    -PACKAGE_STRING='sixel 1.8.2'
    +PACKAGE_VERSION='1.8.3'
    +PACKAGE_STRING='sixel 1.8.3'
     PACKAGE_BUGREPORT='saitoha@me.com'
     PACKAGE_URL=''
     
    @@ -1393,7 +1393,7 @@ if test "$ac_init_help" = "long"; then
       # Omit some internal or obsolete options to make the list less imposing.
       # This message is too long to be a string in the A/UX 3.1 sh.
       cat <<_ACEOF
    -\`configure' configures sixel 1.8.2 to adapt to many kinds of systems.
    +\`configure' configures sixel 1.8.3 to adapt to many kinds of systems.
     
     Usage: $0 [OPTION]... [VAR=VALUE]...
     
    @@ -1463,7 +1463,7 @@ fi
     
     if test -n "$ac_init_help"; then
       case $ac_init_help in
    -     short | recursive ) echo "Configuration of sixel 1.8.2:";;
    +     short | recursive ) echo "Configuration of sixel 1.8.3:";;
        esac
       cat <<\_ACEOF
     
    @@ -1612,7 +1612,7 @@ fi
     test -n "$ac_init_help" && exit $ac_status
     if $ac_init_version; then
       cat <<\_ACEOF
    -sixel configure 1.8.2
    +sixel configure 1.8.3
     generated by GNU Autoconf 2.69
     
     Copyright (C) 2012 Free Software Foundation, Inc.
    @@ -2027,7 +2027,7 @@ cat >config.log <<_ACEOF
     This file contains any messages produced by compilers while
     running configure, to aid debugging if configure makes a mistake.
     
    -It was created by sixel $as_me 1.8.2, which was
    +It was created by sixel $as_me 1.8.3, which was
     generated by GNU Autoconf 2.69.  Invocation command line was
     
       $ $0 $@
    @@ -2970,7 +2970,7 @@ fi
     
     # Define the identity of the package.
      PACKAGE='sixel'
    - VERSION='1.8.2'
    + VERSION='1.8.3'
     
     
     cat >>confdefs.h <<_ACEOF
    @@ -16373,7 +16373,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
     # report actual input values of CONFIG_FILES etc. instead of their
     # values after options handling.
     ac_log="
    -This file was extended by sixel $as_me 1.8.2, which was
    +This file was extended by sixel $as_me 1.8.3, which was
     generated by GNU Autoconf 2.69.  Invocation command line was
     
       CONFIG_FILES    = $CONFIG_FILES
    @@ -16439,7 +16439,7 @@ _ACEOF
     cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
     ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
     ac_cs_version="\\
    -sixel config.status 1.8.2
    +sixel config.status 1.8.3
     configured by $0, generated by GNU Autoconf 2.69,
       with options \\"\$ac_cs_config\\"
     
    
  • configure.ac+1 1 modified
    @@ -3,7 +3,7 @@
     
     AC_PREREQ([2.60])
     LT_PREREQ([2.4])
    -AC_INIT([sixel], [1.8.2], [saitoha@me.com])
    +AC_INIT([sixel], [1.8.3], [saitoha@me.com])
     LS_LT_CURRENT=1
     LS_LT_REVISION=6
     LS_LT_AGE=0
    
  • converters/img2sixel.1+5 0 modified
    @@ -496,6 +496,11 @@ Yusuke Endoh <mame@ruby-lang.org>
     mattn <mattn.jp@gmail.com>
     Akinori Hattori <hattya@gentoo.org>
     Øyvind Kolås <pippin@gimp.org>
    +Henri Salo (@fgeek)
    +hongxu (@HongxuChen)
    +pwd (@YourButterfly)
    +Nicholas Luedtke (@nluedtke)
    +cool-tomato (@cool-tomato)
     .fi
     
     
    
  • include/sixel.h.in+4 0 modified
    @@ -60,6 +60,7 @@ typedef int SIXELSTATUS;
     #define SIXEL_BAD_ALLOCATION    (SIXEL_RUNTIME_ERROR | 0x0001)  /* malloc() failed */
     #define SIXEL_BAD_ARGUMENT      (SIXEL_RUNTIME_ERROR | 0x0002)  /* bad argument detected */
     #define SIXEL_BAD_INPUT         (SIXEL_RUNTIME_ERROR | 0x0003)  /* bad input detected */
    +#define SIXEL_BAD_INTEGER_OVERFLOW (SIXEL_RUNTIME_ERROR | 0x0004)  /* integer overflow */
     
     #define SIXEL_NOT_IMPLEMENTED   (SIXEL_FEATURE_ERROR | 0x0001)  /* feature not implemented */
     
    @@ -366,6 +367,9 @@ typedef int SIXELSTATUS;
     #define SIXEL_OPTFLAG_VERSION           ('V')  /* -V, --version: show version and license info */
     #define SIXEL_OPTFLAG_HELP              ('H')  /* -H, --help: show this help */
     
    +#define SIXEL_WIDTH_LIMIT               1000000
    +#define SIXEL_HEIGHT_LIMIT              1000000
    +
     #if SIXEL_USE_DEPRECATED_SYMBOLS
     /* output character size */
     enum characterSize {
    
  • NEWS+41 0 modified
    @@ -2,6 +2,47 @@
                       ------------------------------
                        What's new in libsixel-1.8 ?
                       ------------------------------
    +
    +* Security fix for CVE-2018-19757 (#79), NULL pointer dereference problem,
    +  reported by @nluedtke and fixed by @knok (#91, #94).
    +
    +* Security fix for CVE-2018-19762 (#81), heap-based buffer overflow problem,
    +  reported by @nluedtke and fixed by @knok (#92).
    +
    +* Security fix for CVE-2018-19756 (#80), heap-based buffer over-read problem,
    +  reported by @nluedtke and fixed by @knok (#93).
    +
    +* Security fix for CVE-2018-19763 (#82), heap-based buffer over-read problem,
    +  reported by @nluedtke and fixed by @knok (#95).
    +
    +* Security fix for CVE-2018-19761, illegal address access, fixed by @knok (#96).
    +
    +* Security fix for CVE-2018-19759, heap-based buffer over-read problem, fixed by @knok (#98).
    +
    +* Security fix for CVE-2018-3753 (#83), infinite loop problem,
    +  reported by @cool-tomato and fixed by @knok (#99).
    +
    +* Security fix for CVE-2018-19759 (#102),
    +  heap-based buffer over-read that will cause a denial of service.
    +  reported and fixed by @YourButterfly. (#106)
    +
    +* Security fix for CVE-2019-19635 (#103), heap-based buffer overflow,
    +  reported and fixed by @YourButterfly. (#106)
    +
    +* Security fix for CVE-2019-19636 (#104) and CVE-2019-19637 (#105), integer overflow problem.
    +  reported and fixed by @YourButterfly. (#106)
    +
    +* gif loader: check LZW code size (Issue #75), Thanks to @HongxuChen.
    +              https://github.com/saitoha/libsixel/commit/7808a06b88c11dbc502318cdd51fa374f8cd47ee
    +
    +* core: Fix a global-buffer-overflow problem (Issue #72), Thanks to @fgeek.
    +        https://github.com/saitoha/libsixel/commit/c868b59ec89bdb24c42a0de89e5319a989076c66
    +
    +* core: Fix unexpected hangs/performance issues (Issue #76), Thanks to @HongxuChen.
    +        https://github.com/saitoha/libsixel/commit/88561b7a810017b91d26b6273323dde4b6f9b273
    +        https://github.com/saitoha/libsixel/commit/2d3d9ffe8ab886b7bc670fd896d63c628436cc66
    +        https://github.com/saitoha/libsixel/commit/c9363cd1d5929e1d721af9f09633061dfa8152fe
    +
     * core: Upgrade stb_image to 2.19.
     
     * core: Introduce new dithering method, a_dither / x_dither (http://pippin.gimp.org/a_dither/).
    
  • package.json+1 1 modified
    @@ -1,6 +1,6 @@
     {
       "name": "libsixel",
    -  "version": "1.8.2",
    +  "version": "1.8.3",
       "repo": "saitoha/libsixel",
       "description": "A lightweight, fast implementation of DEC SIXEL graphics codec",
       "keywords": ["terminal", "graphics", "image", "sixel"],
    
  • README.md+52 1 modified
    @@ -299,6 +299,18 @@ $ xterm -xrm "XTerm*decTerminalID: vt340" -xrm "XTerm*numColorRegisters: 256"
     - cancer
       [https://github.com/meh/cancer/](https://github.com/meh/cancer)
     
    +- wezterm
    +  [https://github.com/wez/wezterm](https://github.com/wez/wezterm)
    +
    +- aminal
    +  [https://github.com/liamg/aminal](https://github.com/liamg/aminal)
    +
    +- iTerm2 (>= 3.0.0)
    +  [https://gitlab.com/gnachman/iterm2](https://gitlab.com/gnachman/iterm2)
    +
    +- st-sixel
    +  [https://github.com/galatolofederico/st-sixel](https://github.com/galatolofederico/st-sixel)
    +
     
     ## Install
     
    @@ -309,7 +321,7 @@ You can install libsixel via the following package systems.
     - [FreeBSD ports](http://portsmon.freebsd.org/portoverview.py?category=graphics&portname=libsixel)
     - [DPorts](https://github.com/DragonFlyBSD/DPorts/tree/master/graphics/libsixel)
     - [pkgsrc](http://cvsweb.netbsd.org/bsdweb.cgi/pkgsrc/graphics/libsixel/)
    -- [Homebrew tap](https://github.com/aki017/homebrew-sixel)
    +- [Homebrew](https://formulae.brew.sh/formula/libsixel)
     - [yacp](https://github.com/fd00/yacp/tree/master/libsixel)
     - [Debian](https://packages.debian.org/search?searchon=names&keywords=libsixel)
     - [AUR](https://aur.archlinux.org/packages/libsixel-git/)
    @@ -1044,6 +1056,12 @@ The MIT License (MIT)
     - [@turenar](https://github.com/turenar/)
     - [@mame](https://github.com/mame/)
     - [@hodefoting](https://github.com/hodefoting/)
    +- [@fCorleone](@https://github.com/fCorleone)
    +- [@fgeek](https://github.com/fgeek/)
    +- [@HongxuChen](https://github.com/HongxuChen/)
    +- [@YourButterfly](https://github.com/YourButterfly/)
    +- [@nluedtke](https://github.com/nluedtke/)
    +- [@cool-tomato](https://github.com/cool-tomato/)
     
     ## Contributing
     
    @@ -1459,3 +1477,36 @@ We are greatly inspired by the quality of ImageMagick and added some resampling
     
     - [gr framework](http://gr-framework.org/)
     
    +- [o2sh/onefetch](https://github.com/o2sh/onefetch)
    +
    +- [lesnitsky/sixel-decoder](https://github.com/lesnitsky/sixel-decoder)
    +
    +- [unhappychoice/irasutoya-cli](https://github.com/unhappychoice/irasutoya-cli)
    +
    +- [ushitora-anqou/tinysixel](https://github.com/ushitora-anqou/tinysixel)
    +
    +- [adzierzanowski/timg](https://github.com/adzierzanowski/timg)
    +
    +- [SAT1226/Minase](https://github.com/SAT1226/Minase)
    +
    +- [danr/neptyne](https://github.com/danr/neptyne)
    +
    +- [klamonte/jexer](https://github.com/klamonte/jexer)
    +
    +- [ar90n/teimpy](https://github.com/ar90n/teimpy)
    +
    +- [fastai](https://github.com/fastai/fastai)
    +
    +- [coderobe/crixel](https://github.com/coderobe/crixel)
    +
    +- [itchyny/mkrg](https://github.com/itchyny/mkrg)
    +
    +- [tshort/SixelTerm.jl](https://github.com/tshort/SixelTerm.jl)
    +
    +- [dsanson/termpdf](https://github.com/dsanson/termpdf)
    +
    +- [otiai10/amesh](https://github.com/otiai10/amesh)
    +
    +- [hpjansson/chafa](https://github.com/hpjansson/chafa)
    +
    +- [m-j-w/TerminalGraphics.jl](https://github.com/m-j-w/TerminalGraphics.jl)
    
  • src/allocator.c+5 0 modified
    @@ -147,6 +147,11 @@ sixel_allocator_malloc(
         assert(allocator);
         assert(allocator->fn_malloc);
     
    +    if (n == 0) {
    +        sixel_helper_set_additional_message(
    +            "sixel_allocator_malloc: called with n == 0");
    +        return NULL;
    +    }
         return allocator->fn_malloc(n);
     }
     
    
  • src/decoder.c+5 0 modified
    @@ -315,6 +315,11 @@ sixel_decoder_decode(
             goto end;
         }
     
    +    if (sx > SIXEL_WIDTH_LIMIT || sy > SIXEL_HEIGHT_LIMIT) {
    +        status = SIXEL_BAD_INPUT;
    +        goto end;
    +    }
    +
         status = sixel_helper_write_image_file(indexed_pixels, sx, sy, palette,
                                                SIXEL_PIXELFORMAT_PAL8,
                                                decoder->output,
    
  • src/fromgif.c+59 24 modified
    @@ -58,20 +58,25 @@ typedef struct
        unsigned char suffix;
     } gif_lzw;
     
    +enum {
    +   gif_lzw_max_code_size = 12
    +};
    +
     typedef struct
     {
        int w, h;
        unsigned char *out;  /* output buffer (always 4 components) */
        int flags, bgindex, ratio, transparent, eflags;
        unsigned char pal[256][3];
        unsigned char lpal[256][3];
    -   gif_lzw codes[4096];
    +   gif_lzw codes[1 << gif_lzw_max_code_size];
        unsigned char *color_table;
        int parse, step;
        int lflags;
        int start_x, start_y;
        int max_x, max_y;
        int cur_x, cur_y;
    +   int actual_width, actual_height;
        int line_size;
        int loop_count;
        int delay;
    @@ -270,15 +275,22 @@ gif_out_code(
             return;
         }
     
    -    g->out[g->cur_x + g->cur_y] = g->codes[code].suffix;
    +    g->out[g->cur_x + g->cur_y * g->line_size] = g->codes[code].suffix;
    +    if (g->cur_x >= g->actual_width) {
    +        g->actual_width = g->cur_x + 1;
    +    }
    +    if (g->cur_y >= g->actual_height) {
    +        g->actual_height = g->cur_y + 1;
    +    }
    +
         g->cur_x++;
     
         if (g->cur_x >= g->max_x) {
             g->cur_x = g->start_x;
             g->cur_y += g->step;
     
             while (g->cur_y >= g->max_y && g->parse > 0) {
    -            g->step = (1 << g->parse) * g->line_size;
    +            g->step = 1 << g->parse;
                 g->cur_y = g->start_y + (g->step >> 1);
                 --g->parse;
             }
    @@ -299,7 +311,15 @@ gif_process_raster(
         signed int codesize, codemask, avail, oldcode, bits, valid_bits, clear;
         gif_lzw *p;
     
    +    /* LZW Minimum Code Size */
         lzw_cs = gif_get8(s);
    +    if (lzw_cs > gif_lzw_max_code_size) {
    +        sixel_helper_set_additional_message(
    +            "Unsupported GIF (LZW code size)");
    +        status = SIXEL_RUNTIME_ERROR;
    +        goto end;
    +    }
    +
         clear = 1 << lzw_cs;
         first = 1;
         codesize = lzw_cs + 1;
    @@ -353,7 +373,7 @@ gif_process_raster(
                         goto end;
                     }
                     if (oldcode >= 0) {
    -                    if (avail < 4096) {
    +                    if (avail < (1 << gif_lzw_max_code_size)) {
                             p = &g->codes[avail++];
                             p->prefix = (signed short) oldcode;
                             p->first = g->codes[oldcode].first;
    @@ -408,36 +428,51 @@ gif_load_next(
     
         for (;;) {
             switch (gif_get8(s)) {
    -        case 0x2C: /* Image Descriptor */
    -            x = gif_get16le(s);
    -            y = gif_get16le(s);
    -            w = gif_get16le(s);
    -            h = gif_get16le(s);
    +        case 0x2C:  /* Image Separator (1 byte) */
    +            x = gif_get16le(s);  /* Image Left Position (2 bytes)*/
    +            y = gif_get16le(s);  /* Image Top Position (2 bytes) */
    +            w = gif_get16le(s);  /* Image Width (2 bytes) */
    +            h = gif_get16le(s);  /* Image Height (2 bytes) */
                 if (((x + w) > (g->w)) || ((y + h) > (g->h))) {
                     sixel_helper_set_additional_message(
    -                    "corrupt GIF (reason: bad Image Descriptor).");
    +                    "corrupt GIF (reason: bad Image Separator).");
                     status = SIXEL_RUNTIME_ERROR;
                     goto end;
                 }
     
                 g->line_size = g->w;
                 g->start_x = x;
    -            g->start_y = y * g->line_size;
    +            g->start_y = y;
                 g->max_x   = g->start_x + w;
    -            g->max_y   = g->start_y + h * g->line_size;
    +            g->max_y   = g->start_y + h;
                 g->cur_x   = g->start_x;
                 g->cur_y   = g->start_y;
    -
    +            g->actual_width   = g->start_x;
    +            g->actual_height   = g->start_y;
    +
    +            /* Packed Fields (1 byte)
    +             * +-+-+-+--+---+
    +             * | | | |  |   |
    +             * +-+-+-+--+---+
    +             *  | | |  |  |
    +             *  | | |  |  +- Size of Local Color Table (3 bits)
    +             *  | | |  +- Reserved (2 bits)
    +             *  | | +- Sort Flag (1 bit)
    +             *  | +- Interlace Flag (1 bit)
    +             *  +- Local Color Table Flag (1 bit)
    +             */
                 g->lflags = gif_get8(s);
     
    +            /* Interlace Flag */
                 if (g->lflags & 0x40) {
    -                g->step = 8 * g->line_size; /* first interlaced spacing */
    +                g->step = 8; /* first interlaced spacing */
                     g->parse = 3;
                 } else {
    -                g->step = g->line_size;
    +                g->step = 1;
                     g->parse = 0;
                 }
     
    +            /* Local Color Table Flag */
                 if (g->lflags & 0x80) {
                     gif_parse_colortable(s,
                                          g->lpal,
    @@ -465,13 +500,13 @@ gif_load_next(
                 }
                 goto end;
     
    -        case 0x21: /* Comment Extension. */
    +        case 0x21:  /* Comment Extension. */
                 switch (gif_get8(s)) {
    -            case 0x01: /* Plain Text Extension */
    +            case 0x01:  /* Plain Text Extension */
                     break;
    -            case 0x21: /* Comment Extension */
    +            case 0x21:  /* Comment Extension */
                     break;
    -            case 0xF9: /* Graphic Control Extension */
    +            case 0xF9:  /* Graphic Control Extension */
                     len = gif_get8(s); /* block size */
                     if (len == 4) {
                         g->eflags = gif_get8(s);
    @@ -482,8 +517,8 @@ gif_load_next(
                         break;
                     }
                     break;
    -            case 0xFF: /* Application Extension */
    -                len = gif_get8(s); /* block size */
    +            case 0xFF:  /* Application Extension */
    +                len = gif_get8(s);  /* block size */
                     if (s->img_buffer + len > s->img_buffer_end) {
                         status = SIXEL_RUNTIME_ERROR;
                         goto end;
    @@ -516,7 +551,7 @@ gif_load_next(
                 }
                 break;
     
    -        case 0x3B: /* gif stream termination code */
    +        case 0x3B:  /* gif stream termination code */
                 g->is_terminated = 1;
                 status = SIXEL_OK;
                 goto end;
    @@ -604,8 +639,8 @@ load_gif(
                     break;
                 }
     
    -            frame->width = g.w;
    -            frame->height = g.h;
    +            frame->width = g.actual_width;
    +            frame->height = g.actual_height;
                 status = gif_init_frame(frame, &g, bgcolor, reqcolors, fuse_palette);
                 if (status != SIXEL_OK) {
                     goto end;
    
  • src/frompnm.c+2 2 modified
    @@ -166,7 +166,7 @@ load_pnm(unsigned char      /* in */  *p,
         height = 0;
         for (; *s >= '0' && *s <= '9'; ++s) {
             height = height * 10 + (*s - '0');
    -        if (width > PNM_MAX_WIDTH) {
    +        if (height > PNM_MAX_HEIGHT) {
                 status = SIXEL_RUNTIME_ERROR;
                 sprintf(
                   message,
    @@ -193,7 +193,7 @@ load_pnm(unsigned char      /* in */  *p,
             for (; *s >= '0' && *s <= '9'; ++s) {
                 deps = deps * 10 + (*s - '0');
             }
    -        if (width > PNM_MAX_WIDTH) {
    +        if (deps > PNM_MAX_DEPTH) {
                 status = SIXEL_RUNTIME_ERROR;
                 sprintf(
                   message,
    
  • src/fromsixel.c+40 6 modified
    @@ -52,6 +52,7 @@
     #include <stdio.h>
     #include <ctype.h>   /* isdigit */
     #include <string.h>  /* memcpy */
    +#include <limits.h>
     
     #if defined(HAVE_INTTYPES_H)
     # include <inttypes.h>
    @@ -290,7 +291,7 @@ image_buffer_resize(
     
         size = (size_t)(width * height);
         alt_buffer = (unsigned char *)sixel_allocator_malloc(allocator, size);
    -    if (alt_buffer == NULL) {
    +    if (alt_buffer == NULL || size == 0) {
             /* free source image */
             sixel_allocator_free(allocator, image->data);
             image->data = NULL;
    @@ -367,6 +368,16 @@ parser_context_init(parser_context_t *context)
         return status;
     }
     
    +SIXELSTATUS safe_addition_for_params(parser_context_t *context, unsigned char *p){
    +    int x;
    +
    +    x = *p - '0'; /* 0 <= x <= 9 */
    +    if ((context->param > INT_MAX / 10) || (x > INT_MAX - context->param * 10)) {
    +        return SIXEL_BAD_INTEGER_OVERFLOW;
    +    }
    +    context->param = context->param * 10 + x;
    +    return SIXEL_OK;
    +}
     
     /* convert sixel data into indexed pixel bytes and palette data */
     SIXELAPI SIXELSTATUS
    @@ -446,7 +457,10 @@ sixel_decode_raw_impl(
                     if (context->param < 0) {
                         context->param = 0;
                     }
    -                context->param = context->param * 10 + *p - '0';
    +                status = safe_addition_for_params(context, p);
    +                if (SIXEL_FAILED(status)) {
    +                    goto end;
    +                }
                     p++;
                     break;
                 case ';':
    @@ -572,6 +586,10 @@ sixel_decode_raw_impl(
                             image->ncolors = context->color_index;
                         }
     
    +                    if (context->pos_x < 0 || context->pos_y < 0) {
    +                        status = SIXEL_BAD_INPUT;
    +                        goto end;
    +                    }
                         bits = *p - '?';
     
                         if (bits == 0) {
    @@ -647,7 +665,10 @@ sixel_decode_raw_impl(
                 case '7':
                 case '8':
                 case '9':
    -                context->param = context->param * 10 + *p - '0';
    +                status = safe_addition_for_params(context, p);
    +                if (SIXEL_FAILED(status)) {
    +                    goto end;
    +                }
                     p++;
                     break;
                 case ';':
    @@ -721,14 +742,21 @@ sixel_decode_raw_impl(
                 case '7':
                 case '8':
                 case '9':
    -                context->param = context->param * 10 + *p - '0';
    +                status = safe_addition_for_params(context, p);
    +                if (SIXEL_FAILED(status)) {
    +                    goto end;
    +                }
                     p++;
                     break;
                 default:
                     context->repeat_count = context->param;
                     if (context->repeat_count == 0) {
                         context->repeat_count = 1;
                     }
    +                if (context->repeat_count > 0xffff) { /* check too huge number */
    +                    status = SIXEL_BAD_INPUT;
    +                    goto end;
    +                }
                     context->state = PS_DECSIXEL;
                     context->param = 0;
                     context->nparams = 0;
    @@ -753,7 +781,10 @@ sixel_decode_raw_impl(
                 case '7':
                 case '8':
                 case '9':
    -                context->param = context->param * 10 + *p - '0';
    +                status = safe_addition_for_params(context, p);
    +                if (SIXEL_FAILED(status)) {
    +                    goto end;
    +                }
                     p++;
                     break;
                 case ';':
    @@ -884,7 +915,10 @@ sixel_decode_raw(
         }
     
         *ncolors = image.ncolors + 1;
    -    *palette = (unsigned char *)sixel_allocator_malloc(allocator, (size_t)(*ncolors * 3));
    +    int alloc_size = *ncolors;
    +    if (alloc_size < 256) // memory access range should be 0 <= 255 (in write_png_to_file)
    +        alloc_size = 256;
    +    *palette = (unsigned char *)sixel_allocator_malloc(allocator, (size_t)(alloc_size * 3));
         if (palette == NULL) {
             sixel_allocator_free(allocator, image.data);
             sixel_helper_set_additional_message(
    
  • src/loader.c+18 2 modified
    @@ -195,6 +195,12 @@ load_jpeg(unsigned char **result,
     
         while (cinfo.output_scanline < cinfo.output_height) {
             jpeg_read_scanlines(&cinfo, buffer, 1);
    +        if (cinfo.err->num_warnings > 0) {
    +            sixel_helper_set_additional_message(
    +                "jpeg_read_scanlines: error/warining occuered.");
    +            status = SIXEL_BAD_INPUT;
    +            goto end;
    +        }
             memcpy(*result + (cinfo.output_scanline - 1) * row_stride, buffer[0], row_stride);
         }
     
    @@ -941,10 +947,11 @@ load_with_gdkpixbuf(
         GdkPixbuf *pixbuf;
         GdkPixbufAnimation *animation;
         GdkPixbufLoader *loader = NULL;
    -#if 1
         GdkPixbufAnimationIter *it;
    +#pragma GCC diagnostic push
    +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
         GTimeVal time_val;
    -#endif
    +#pragma GCC diagnostic pop
         sixel_frame_t *frame = NULL;
         int stride;
         unsigned char *p;
    @@ -963,7 +970,10 @@ load_with_gdkpixbuf(
     #if (!GLIB_CHECK_VERSION(2, 36, 0))
         g_type_init();
     #endif
    +#pragma GCC diagnostic push
    +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
         g_get_current_time(&time_val);
    +#pragma GCC diagnostic pop
         loader = gdk_pixbuf_loader_new();
         gdk_pixbuf_loader_write(loader, pchunk->buffer, pchunk->size, NULL);
         animation = gdk_pixbuf_loader_get_animation(loader);
    @@ -1006,15 +1016,21 @@ load_with_gdkpixbuf(
                 goto end;
             }
         } else {
    +#pragma GCC diagnostic push
    +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
             g_get_current_time(&time_val);
    +#pragma GCC diagnostic pop
     
             frame->frame_no = 0;
     
             it = gdk_pixbuf_animation_get_iter(animation, &time_val);
             for (;;) {
                 while (!gdk_pixbuf_animation_iter_on_currently_loading_frame(it)) {
                     frame->delay = gdk_pixbuf_animation_iter_get_delay_time(it);
    +#pragma GCC diagnostic push
    +#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
                     g_time_val_add(&time_val, frame->delay * 1000);
    +#pragma GCC diagnostic pop
                     frame->delay /= 10;
                     pixbuf = gdk_pixbuf_animation_iter_get_pixbuf(it);
                     if (pixbuf == NULL) {
    
  • src/status.c+6 0 modified
    @@ -46,6 +46,7 @@
     #define SIXEL_MESSAGE_BAD_ALLOCATION    ("runtime error: bad allocation error")
     #define SIXEL_MESSAGE_BAD_ARGUMENT      ("runtime error: bad argument detected")
     #define SIXEL_MESSAGE_BAD_INPUT         ("runtime error: bad input detected")
    +#define SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW  ("runtime error: integer overflow")
     #define SIXEL_MESSAGE_RUNTIME_ERROR     ("runtime error")
     #define SIXEL_MESSAGE_LOGIC_ERROR       ("logic error")
     #define SIXEL_MESSAGE_NOT_IMPLEMENTED   ("feature error: not implemented")
    @@ -68,6 +69,8 @@ sixel_helper_set_additional_message(
     {
         size_t len;
     
    +    if (message == 0)
    +        return;
         len = strlen(message);
         memcpy(g_buffer, message, len < sizeof(g_buffer) ? len: sizeof(g_buffer) - 1);
         g_buffer[sizeof(g_buffer) - 1] = 0;
    @@ -118,6 +121,9 @@ sixel_helper_format_error(
                 case SIXEL_BAD_INPUT:
                     error_string = SIXEL_MESSAGE_BAD_INPUT;
                     break;
    +            case SIXEL_BAD_INTEGER_OVERFLOW:
    +                error_string = SIXEL_MESSAGE_BAD_INTEGER_OVERFLOW;
    +                break;
                 default:
                     error_string = SIXEL_MESSAGE_RUNTIME_ERROR;
                     break;
    
  • src/stb_image.h+14 4 modified
    @@ -845,6 +845,8 @@ static const char *stbi__g_failure_reason;
     
     STBIDEF const char *stbi_failure_reason(void)
     {
    +   if (stbi__g_failure_reason == NULL)
    +      stbi__g_failure_reason = "unknwon error, refer error message before assignment";
        return stbi__g_failure_reason;
     }
     
    @@ -2017,6 +2019,7 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
           // first scan for DC coefficient, must be first
           memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
           t = stbi__jpeg_huff_decode(j, hdc);
    +      if (t < 0 || t >= 16) return stbi__err("bad huffman code","Corrupt JPEG");
           diff = t ? stbi__extend_receive(j, t) : 0;
     
           dc = j->img_comp[b].dc_pred + diff;
    @@ -5566,6 +5569,7 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
              //   OK, if I need to read a pixel, do it now
              if ( read_next_pixel )
              {
    +            if (stbi__at_eof(s))   return stbi__errpuc("bad file","TGA file too short");
                 //   load however much data we did have
                 if ( tga_indexed )
                 {
    @@ -5666,6 +5670,7 @@ static int stbi__psd_decode_rle(stbi__context *s, stbi_uc *p, int pixelCount)
     
        count = 0;
        while ((nleft = pixelCount - count) > 0) {
    +      if (stbi__at_eof(s))   return 0;
           len = stbi__get8(s);
           if (len == 128) {
              // No-op.
    @@ -5780,7 +5785,6 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
     
        // Initialize the data to zero.
        //memset( out, 0, pixelCount * 4 );
    -
        // Finally, the image data.
        if (compression) {
           // RLE as used by .PSD and .TIFF
    @@ -5835,16 +5839,22 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
              } else {
                 if (ri->bits_per_channel == 16) {    // output bpc
                    stbi__uint16 *q = ((stbi__uint16 *) out) + channel;
    -               for (i = 0; i < pixelCount; i++, q += 4)
    +               for (i = 0; i < pixelCount; i++, q += 4) {
    +                  if (stbi__at_eof(s))   return stbi__errpuc("bad file","PSD file too short");
                       *q = (stbi__uint16) stbi__get16be(s);
    +               }
                 } else {
                    stbi_uc *p = out+channel;
                    if (bitdepth == 16) {  // input bpc
    -                  for (i = 0; i < pixelCount; i++, p += 4)
    +                  for (i = 0; i < pixelCount; i++, p += 4) {
    +                     if (stbi__at_eof(s))   return stbi__errpuc("bad file","PSD file too short");
                          *p = (stbi_uc) (stbi__get16be(s) >> 8);
    +                  }
                    } else {
    -                  for (i = 0; i < pixelCount; i++, p += 4)
    +                  for (i = 0; i < pixelCount; i++, p += 4) {
    +                     if (stbi__at_eof(s))   return stbi__errpuc("bad file","PSD file too short");
                          *p = stbi__get8(s);
    +                  }
                    }
                 }
              }
    
  • src/tosixel.c+25 1 modified
    @@ -21,6 +21,7 @@
     #include <stdio.h>
     #include <stdlib.h>
     #include <string.h>
    +#include <limits.h>
     
     #if defined(HAVE_INTTYPES_H)
     # include <inttypes.h>
    @@ -502,6 +503,7 @@ sixel_encode_body(
         int mx;
         int len;
         int pix;
    +    int check_integer_overflow;
         unsigned char *map = NULL;
         sixel_node_t *np, *tp, top;
         int fillable;
    @@ -557,8 +559,30 @@ sixel_encode_body(
                 fillable = 1;
             }
             for (x = 0; x < width; x++) {
    -            pix = pixels[y * width + x];  /* color index */
    +            if (y > INT_MAX / width) {
    +                /* integer overflow */
    +                status = SIXEL_BAD_INTEGER_OVERFLOW;
    +                goto end;
    +            }
    +            check_integer_overflow = y * width;
    +            if (check_integer_overflow > INT_MAX - x) {
    +                /* integer overflow */
    +                status = SIXEL_BAD_INTEGER_OVERFLOW;
    +                goto end;
    +            }
    +            pix = pixels[check_integer_overflow + x];  /* color index */
                 if (pix >= 0 && pix < ncolors && pix != keycolor) {
    +                if (pix > INT_MAX / width) {
    +                    /* integer overflow */
    +                    status = SIXEL_BAD_INTEGER_OVERFLOW;
    +                    goto end;
    +                }
    +                check_integer_overflow = pix * width;
    +                if (check_integer_overflow > INT_MAX - x) {
    +                    /* integer overflow */
    +                    status = SIXEL_BAD_INTEGER_OVERFLOW;
    +                    goto end;
    +                }
                     map[pix * width + x] |= (1 << i);
                 }
                 else if (!palstate) {
    
  • .travis.yml+3 3 modified
    @@ -11,8 +11,8 @@ matrix:
         env: XCC=clang HOST= PREFIX=/usr/local DEBUG="--enable-tests --enable-debug" WINE= LIBCURL=--without-libcurl JPEG=--without-jpeg PNG=--without-png
       - os: linux
         env: XCC=i686-w64-mingw32-gcc HOST="--host=i686-w64-mingw32" PREFIX="/usr/i686-w64-mingw32" DEBUG="--enable-tests --enable-debug" WINE=wine
    -  - os: linux
    -    env: XCC=i586-mingw32msvc-gcc HOST="--host=i586-mingw32msvc" PREFIX="/usr/i586-mingw32msvc" WINE=wine
    +#  - os: linux
    +#    env: XCC=i586-mingw32msvc-gcc HOST="--host=i586-mingw32msvc" PREFIX="/usr/i586-mingw32msvc" WINE=wine
       - os: linux
         env: XCC=x86_64-w64-mingw32-gcc HOST="--host=x86_64-w64-mingw32" PREFIX="/usr/x86_64-w64-mingw32" DEBUG="--enable-tests --enable-debug" WINE=wine64
       - os: linux
    @@ -68,7 +68,7 @@ before_install:
       - "if [ x$TRAVIS_OS_NAME = xlinux -a x$XCC = xclang ]; then sudo apt-get install -qq clang; fi"
       - "if [ x$TRAVIS_OS_NAME = xlinux -a x$XCC = xgcc ]; then sudo apt-get install -qq gcc; fi"
       - "if [ x$TRAVIS_OS_NAME = xlinux -a x$XCC = xi686-w64-mingw32-gcc ]; then sudo apt-get install -qq gcc-mingw-w64-i686 binutils-mingw-w64-i686; fi"
    -  - "if [ x$TRAVIS_OS_NAME = xlinux -a x$XCC = xi586-mingw32msvc-gcc ]; then sudo apt-get install -qq mingw32; fi"
    +#  - "if [ x$TRAVIS_OS_NAME = xlinux -a x$XCC = xi586-mingw32msvc-gcc ]; then sudo apt-get install -qq mingw32; fi"
       - "if [ x$TRAVIS_OS_NAME = xlinux -a x$XCC = xx86_64-w64-mingw32-gcc ]; then sudo apt-get install -qq gcc-mingw-w64-x86-64 binutils-mingw-w64-x86-64; fi"
       - "if [ x$TRAVIS_OS_NAME = xlinux -a x$GCOV != x ]; then sudo apt-get install libyaml-dev; fi"
       - "if [ x$TRAVIS_OS_NAME = xosx -a x$GCOV != x ]; then brew install libyaml; fi"
    
7808a06b88c1

gif loader: check LZW code size (Issue #75)

https://github.com/saitoha/libsixelHayaki SaitoAug 1, 2018via nvd-ref
1 file changed · +14 2
  • src/fromgif.c+14 2 modified
    @@ -58,14 +58,18 @@ typedef struct
        unsigned char suffix;
     } gif_lzw;
     
    +enum {
    +   gif_lzw_max_code_size = 12
    +};
    +
     typedef struct
     {
        int w, h;
        unsigned char *out;  /* output buffer (always 4 components) */
        int flags, bgindex, ratio, transparent, eflags;
        unsigned char pal[256][3];
        unsigned char lpal[256][3];
    -   gif_lzw codes[4096];
    +   gif_lzw codes[1 << gif_lzw_max_code_size];
        unsigned char *color_table;
        int parse, step;
        int lflags;
    @@ -299,7 +303,15 @@ gif_process_raster(
         signed int codesize, codemask, avail, oldcode, bits, valid_bits, clear;
         gif_lzw *p;
     
    +    /* LZW Minimum Code Size */
         lzw_cs = gif_get8(s);
    +    if (lzw_cs > gif_lzw_max_code_size) {
    +        sixel_helper_set_additional_message(
    +            "Unsupported GIF (LZW code size)");
    +        status = SIXEL_RUNTIME_ERROR;
    +        goto end;
    +    }
    +
         clear = 1 << lzw_cs;
         first = 1;
         codesize = lzw_cs + 1;
    @@ -353,7 +365,7 @@ gif_process_raster(
                         goto end;
                     }
                     if (oldcode >= 0) {
    -                    if (avail < 4096) {
    +                    if (avail < (1 << gif_lzw_max_code_size)) {
                             p = &g->codes[avail++];
                             p->prefix = (signed short) oldcode;
                             p->first = g->codes[oldcode].first;
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.