CVE-2018-7186 (C, published 2018-02-16T16:29Z)
Description: value: Leptonica before 1.75.3 does not limit the number of characters in a %s format argument to fscanf or sscanf, which allows remote attackers to cause a denial of service (stack-based buffer overflow) or possibly have unspecified other impact via a long string, as demonstrated by the gplotRead and ptaReadStream functions.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-787 \u2014 Out-of-bounds Write
The product writes data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/DanBloomberg/leptonica
Files changed:
README.md
prog/xtractprotos.c
src/gplot.c
src/ptabasic.c
src/sel1.c
Commit message: Security fixes: expect final changes for release 1.75.3.
* Fixed a debian security issue with fscanf() reading a string with
  possible buffer overflow.
* There were also a few similar situations with sscanf().


Vulnerable code:
  * [php](http://en.wikipedia.org/wiki/PHP)  (scripting language for dynamic web pages)
static const l_int32  L_BUF_SIZE = 512;
char         buf[L_BUF_SIZE];
                ret = sscanf(argv[i] + 1, "prestring=%s", buf);
                if ((len = strlen(buf)) > L_BUF_SIZE - 3) {
                ret = sscanf(argv[i] + 1, "protos=%s", buf);
    snprintf(buf, L_BUF_SIZE,
        snprintf(buf, L_BUF_SIZE, "cpp -ansi -DNO_PROTOS %s %s",
 *     Utility for programmatic plotting using gnuplot 7.3.2 or later
 *         ~ output to png (color), ps (mono), x11 (color), latex (mono)
static const l_int32  L_BUF_SIZE = 512;
char     buf[L_BUF_SIZE];
    snprintf(buf, L_BUF_SIZE, "%s.cmd", rootname);
        snprintf(buf, L_BUF_SIZE, "%s.png", newroot);
        snprintf(buf, L_BUF_SIZE, "%s.ps", newroot);
        snprintf(buf, L_BUF_SIZE, "%s.eps", newroot);
        snprintf(buf, L_BUF_SIZE, "%s.tex", newroot);
char       buf[L_BUF_SIZE];
    snprintf(buf, L_BUF_SIZE, "%s.data.%d", gplot->rootname, gplot->nplots);
        snprintf(buf, L_BUF_SIZE, "%f %f\n", valx, valy);
char     buf[L_BUF_SIZE];
    snprintf(buf, L_BUF_SIZE, "gnuplot %s", cmdname);
    snprintf(buf, L_BUF_SIZE, "wgnuplot %s", cmdname);
char     buf[L_BUF_SIZE];
        snprintf(buf, L_BUF_SIZE, "set title '%s'", gplot->title);
        snprintf(buf, L_BUF_SIZE, "set xlabel '%s'", gplot->xlabel);
        snprintf(buf, L_BUF_SIZE, "set ylabel '%s'", gplot->ylabel);
        snprintf(buf, L_BUF_SIZE, "set terminal png; set output '%s'",
        snprintf(buf, L_BUF_SIZE, "set terminal postscript; set output '%s'",
        snprintf(buf, L_BUF_SIZE,
        snprintf(buf, L_BUF_SIZE, "set terminal latex; set output '%s'",
        snprintf(buf, L_BUF_SIZE, "set logscale x");
        snprintf(buf, L_BUF_SIZE, "set logscale y");
            snprintf(buf, L_BUF_SIZE, "plot '%s' title '%s' %s",
                snprintf(buf, L_BUF_SIZE, "plot '%s' title '%s' %s, \\",
                snprintf(buf, L_BUF_SIZE, " '%s' title '%s' %s, \\",
                snprintf(buf, L_BUF_SIZE, " '%s' title '%s' %s",
char     buf[L_BUF_SIZE];
    ignore = fscanf(fp, "Rootname: %s\n", buf);
    ignores = fgets(buf, L_BUF_SIZE, fp);   /* Title: ... */
    ignores = fgets(buf, L_BUF_SIZE, fp);   /* X axis label: ... */
    ignores = fgets(buf, L_BUF_SIZE, fp);   /* Y axis label: ... */
    ignore = fscanf(fp, "Commandfile name: %s\n", buf);
    ignore = fscanf(fp, "Output file name: %s\n", buf);
char       typestr[128];
    if (fscanf(fp, " Number of pts = %d; format = %s\n", &n, typestr) != 2)
static const l_int32  L_BUF_SIZE = 256;
char     combname[L_BUF_SIZE];
        snprintf(combname, L_BUF_SIZE, "sel_comb_%dh", size);
        snprintf(combname, L_BUF_SIZE, "sel_comb_%dv", size);
char     buf[L_BUF_SIZE];
        snprintf(buf, L_BUF_SIZE,
char     linebuf[L_BUF_SIZE];
    if (fgets(linebuf, L_BUF_SIZE, fp) == NULL)
    sscanf(linebuf, "  ------  %s  ------", selname);

Fixed code:
  * [OpenCV](https://github.com/opencv/opencv) (computer vision library)
  * [php](http://en.wikipedia.org/wiki/PHP)  (scripting language for dynamic web pages)
static const l_int32  L_BUFSIZE = 512;  /* hardcoded below in sscanf() */
char         buf[L_BUFSIZE];
                ret = sscanf(argv[i] + 1, "prestring=%490s", buf);
                if ((len = strlen(buf)) > L_BUFSIZE - 3) {
                ret = sscanf(argv[i] + 1, "protos=%490s", buf);
    snprintf(buf, L_BUFSIZE,
        snprintf(buf, L_BUFSIZE, "cpp -ansi -DNO_PROTOS %s %s",
 *     Utility for programmatic plotting using gnuplot 4.6 or later
 *         ~ output to png (color), ps and eps (mono), latex (mono)
static const l_int32  L_BUFSIZE = 512;  /* hardcoded below in fscanf */
char     buf[L_BUFSIZE];
    snprintf(buf, L_BUFSIZE, "%s.cmd", rootname);
        snprintf(buf, L_BUFSIZE, "%s.png", newroot);
        snprintf(buf, L_BUFSIZE, "%s.ps", newroot);
        snprintf(buf, L_BUFSIZE, "%s.eps", newroot);
        snprintf(buf, L_BUFSIZE, "%s.tex", newroot);
char       buf[L_BUFSIZE];
    snprintf(buf, L_BUFSIZE, "%s.data.%d", gplot->rootname, gplot->nplots);
        snprintf(buf, L_BUFSIZE, "%f %f\n", valx, valy);
char     buf[L_BUFSIZE];
    snprintf(buf, L_BUFSIZE, "gnuplot %s", cmdname);
    snprintf(buf, L_BUFSIZE, "wgnuplot %s", cmdname);
char     buf[L_BUFSIZE];
        snprintf(buf, L_BUFSIZE, "set title '%s'", gplot->title);
        snprintf(buf, L_BUFSIZE, "set xlabel '%s'", gplot->xlabel);
        snprintf(buf, L_BUFSIZE, "set ylabel '%s'", gplot->ylabel);
        snprintf(buf, L_BUFSIZE, "set terminal png; set output '%s'",
        snprintf(buf, L_BUFSIZE, "set terminal postscript; set output '%s'",
        snprintf(buf, L_BUFSIZE,
        snprintf(buf, L_BUFSIZE, "set terminal latex; set output '%s'",
        snprintf(buf, L_BUFSIZE, "set logscale x");
        snprintf(buf, L_BUFSIZE, "set logscale y");
            snprintf(buf, L_BUFSIZE, "plot '%s' title '%s' %s",
                snprintf(buf, L_BUFSIZE, "plot '%s' title '%s' %s, \\",
                snprintf(buf, L_BUFSIZE, " '%s' title '%s' %s, \\",
                snprintf(buf, L_BUFSIZE, " '%s' title '%s' %s",
char     buf[L_BUFSIZE];
    ignore = fscanf(fp, "Rootname: %511s\n", buf);  /* L_BUFSIZE - 1 */
    ignores = fgets(buf, L_BUFSIZE, fp);   /* Title: ... */
    ignores = fgets(buf, L_BUFSIZE, fp);   /* X axis label: ... */
    ignores = fgets(buf, L_BUFSIZE, fp);   /* Y axis label: ... */
    ignore = fscanf(fp, "Commandfile name: %511s\n", buf);  /* L_BUFSIZE - 1 */
    ignore = fscanf(fp, "Output file name: %511s\n", buf);
char       typestr[128];  /* hardcoded below in fscanf */
    if (fscanf(fp, " Number of pts = %d; format = %127s\n", &n, typestr) != 2)
static const l_int32  L_BUFSIZE = 256;  /* hardcoded below in sscanf */
char     combname[L_BUFSIZE];
        snprintf(combname, L_BUFSIZE, "sel_comb_%dh", size);
        snprintf(combname, L_BUFSIZE, "sel_comb_%dv", size);
char     buf[L_BUFSIZE];
        snprintf(buf, L_BUFSIZE,
char     linebuf[L_BUFSIZE];
    if (fgets(linebuf, L_BUFSIZE, fp) == NULL)
    sscanf(linebuf, "  ------  %200s  ------", selname);