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().
CVE: CVE-2018-7186
CWE: CWE-119
Vulnerability description: 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.

Project: leptonica
File: gplot.c

gplotWrite(const char  *filename,
           GPLOT       *gplot)
{
FILE  *fp;

    PROCNAME("gplotWrite");

    if (!filename)
        return ERROR_INT("filename not defined", procName, 1);
    if (!gplot)
        return ERROR_INT("gplot not defined", procName, 1);

    if ((fp = fopenWriteStream(filename, "wb")) == NULL)
        return ERROR_INT("stream not opened", procName, 1);

    fprintf(fp, "Gplot Version %d\n", GPLOT_VERSION_NUMBER);
    fprintf(fp, "Rootname: %s\n", gplot->rootname);
    fprintf(fp, "Output format: %d\n", gplot->outformat);
    fprintf(fp, "Title: %s\n", gplot->title);
    fprintf(fp, "X axis label: %s\n", gplot->xlabel);
    fprintf(fp, "Y axis label: %s\n", gplot->ylabel);

    fprintf(fp, "Commandfile name: %s\n", gplot->cmdname);
    fprintf(fp, "\nCommandfile data:");
    sarrayWriteStream(fp, gplot->cmddata);
    fprintf(fp, "\nDatafile names:");
    sarrayWriteStream(fp, gplot->datanames);
    fprintf(fp, "\nPlot data:");
    sarrayWriteStream(fp, gplot->plotdata);
    fprintf(fp, "\nPlot titles:");
    sarrayWriteStream(fp, gplot->plottitles);
    fprintf(fp, "\nPlot styles:");
    numaWriteStream(fp, gplot->plotstyles);

    fprintf(fp, "Number of plots: %d\n", gplot->nplots);
    fprintf(fp, "Output file name: %s\n", gplot->outname);
    fprintf(fp, "Axis scaling: %d\n", gplot->scaling);

    fclose(fp);
    return 0;
}

Project: leptonica
File: ptabasic.c

ptaCreateFromNuma(NUMA  *nax,
                  NUMA  *nay)
{
l_int32    i, n;
l_float32  startx, delx, xval, yval;
PTA       *pta;

    PROCNAME("ptaCreateFromNuma");

    if (!nay)
        return (PTA *)ERROR_PTR("nay not defined", procName, NULL);
    n = numaGetCount(nay);
    if (nax && numaGetCount(nax) != n)
        return (PTA *)ERROR_PTR("nax and nay sizes differ", procName, NULL);

    pta = ptaCreate(n);
    numaGetParameters(nay, &startx, &delx);
    for (i = 0; i < n; i++) {
        if (nax)
            numaGetFValue(nax, i, &xval);
        else  /* use implicit x values from nay */
            xval = startx + i * delx;
        numaGetFValue(nay, i, &yval);
        ptaAddPt(pta, xval, yval);
    }

    return pta;
}

Project: leptonica
File: ptabasic.c

ptaDestroy(PTA  **ppta)
{
PTA  *pta;

    PROCNAME("ptaDestroy");

    if (ppta == NULL) {
        L_WARNING("ptr address is NULL!\n", procName);
        return;
    }

    if ((pta = *ppta) == NULL)
        return;

    ptaChangeRefcount(pta, -1);
    if (ptaGetRefcount(pta) <= 0) {
        LEPT_FREE(pta->x);
        LEPT_FREE(pta->y);
        LEPT_FREE(pta);
    }

    *ppta = NULL;
    return;
}

Project: leptonica
File: ptabasic.c

ptaEmpty(PTA  *pta)
{
    PROCNAME("ptaEmpty");

    if (!pta)
        return ERROR_INT("ptad not defined", procName, 1);
    pta->n = 0;
    return 0;
}

Project: leptonica
File: ptabasic.c

ptaExtendArrays(PTA  *pta)
{
    PROCNAME("ptaExtendArrays");

    if (!pta)
        return ERROR_INT("pta not defined", procName, 1);

    if ((pta->x = (l_float32 *)reallocNew((void **)&pta->x,
                               sizeof(l_float32) * pta->nalloc,
                               2 * sizeof(l_float32) * pta->nalloc)) == NULL)
        return ERROR_INT("new x array not returned", procName, 1);
    if ((pta->y = (l_float32 *)reallocNew((void **)&pta->y,
                               sizeof(l_float32) * pta->nalloc,
                               2 * sizeof(l_float32) * pta->nalloc)) == NULL)
        return ERROR_INT("new y array not returned", procName, 1);

    pta->nalloc = 2 * pta->nalloc;
    return 0;
}

Project: leptonica
File: ptabasic.c

ptaaGetCount(PTAA  *ptaa)
{
    PROCNAME("ptaaGetCount");

    if (!ptaa)
        return ERROR_INT("ptaa not defined", procName, 0);

    return ptaa->n;
}

Project: leptonica
File: ptabasic.c

ptaaGetPt(PTAA       *ptaa,
           l_int32     ipta,
           l_int32     jpt,
           l_float32  *px,
           l_float32  *py)
{
PTA  *pta;

    PROCNAME("ptaaGetPt");

    if (px) *px = 0;
    if (py) *py = 0;
    if (!ptaa)
        return ERROR_INT("ptaa not defined", procName, 1);
    if (ipta < 0 || ipta >= ptaa->n)
        return ERROR_INT("index ipta not valid", procName, 1);

    pta = ptaaGetPta(ptaa, ipta, L_CLONE);
    if (jpt < 0 || jpt >= pta->n) {
        ptaDestroy(&pta);
        return ERROR_INT("index jpt not valid", procName, 1);
    }

    ptaGetPt(pta, jpt, px, py);
    ptaDestroy(&pta);
    return 0;
}

Project: leptonica
File: ptabasic.c

ptaaInitFull(PTAA  *ptaa,
             PTA   *pta)
{
l_int32  n, i;
PTA     *ptat;

    PROCNAME("ptaaInitFull");

    if (!ptaa)
        return ERROR_INT("ptaa not defined", procName, 1);
    if (!pta)
        return ERROR_INT("pta not defined", procName, 1);

    n = ptaa->nalloc;
    ptaa->n = n;
    for (i = 0; i < n; i++) {
        ptat = ptaCopy(pta);
        ptaaReplacePta(ptaa, i, ptat);
    }
    return 0;
}

Project: leptonica
File: ptabasic.c

ptaaRead(const char  *filename)
{
FILE  *fp;
PTAA  *ptaa;

    PROCNAME("ptaaRead");

    if (!filename)
        return (PTAA *)ERROR_PTR("filename not defined", procName, NULL);

    if ((fp = fopenReadStream(filename)) == NULL)
        return (PTAA *)ERROR_PTR("stream not opened", procName, NULL);
    ptaa = ptaaReadStream(fp);
    fclose(fp);
    if (!ptaa)
        return (PTAA *)ERROR_PTR("ptaa not read", procName, NULL);
    return ptaa;
}

Project: leptonica
File: sel1.c

selCreateBrick(l_int32  h,
               l_int32  w,
               l_int32  cy,
               l_int32  cx,
               l_int32  type)
{
l_int32  i, j;
SEL     *sel;

    PROCNAME("selCreateBrick");

    if (h <= 0 || w <= 0)
        return (SEL *)ERROR_PTR("h and w must both be > 0", procName, NULL);
    if (type != SEL_HIT && type != SEL_MISS && type != SEL_DONT_CARE)
        return (SEL *)ERROR_PTR("invalid sel element type", procName, NULL);

    if ((sel = selCreate(h, w, NULL)) == NULL)
        return (SEL *)ERROR_PTR("sel not made", procName, NULL);
    selSetOrigin(sel, cy, cx);
    for (i = 0; i < h; i++)
        for (j = 0; j < w; j++)
            sel->data[i][j] = type;

    return sel;
}

Project: leptonica
File: sel1.c

selGetParameters(SEL      *sel,
                 l_int32  *psy,
                 l_int32  *psx,
                 l_int32  *pcy,
                 l_int32  *pcx)
{
    PROCNAME("selGetParameters");

    if (psy) *psy = 0;
    if (psx) *psx = 0;
    if (pcy) *pcy = 0;
    if (pcx) *pcx = 0;
    if (!sel)
        return ERROR_INT("sel not defined", procName, 1);
    if (psy) *psy = sel->sy;
    if (psx) *psx = sel->sx;
    if (pcy) *pcy = sel->cy;
    if (pcx) *pcx = sel->cx;
    return 0;
}

Project: leptonica
File: sel1.c

selSetName(SEL         *sel,
           const char  *name)
{
    PROCNAME("selSetName");

    if (!sel)
        return ERROR_INT("sel not defined", procName, 1);

    return stringReplace(&sel->name, name);
}

Project: leptonica
File: sel1.c

selaGetSelnames(SELA  *sela)
{
char    *selname;
l_int32  i, n;
SEL     *sel;
SARRAY  *sa;

    PROCNAME("selaGetSelnames");

    if (!sela)
        return (SARRAY *)ERROR_PTR("sela not defined", procName, NULL);
    if ((n = selaGetCount(sela)) == 0)
        return (SARRAY *)ERROR_PTR("no sels in sela", procName, NULL);

    if ((sa = sarrayCreate(n)) == NULL)
        return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
    for (i = 0; i < n; i++) {
        sel = selaGetSel(sela, i);
        selname = selGetName(sel);
        sarrayAddString(sa, selname, L_COPY);
    }

    return sa;
}