Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffer overflow in HPDF_FToA #111

Closed
jjvbsag opened this issue Nov 9, 2015 · 1 comment
Closed

Buffer overflow in HPDF_FToA #111

jjvbsag opened this issue Nov 9, 2015 · 1 comment

Comments

@jjvbsag
Copy link

jjvbsag commented Nov 9, 2015

With ac6052c the following patch was done

-#define HPDF_LIMIT_MAX_REAL            32767
-#define HPDF_LIMIT_MIN_REAL            -32767
+#define HPDF_LIMIT_MAX_REAL             3.4E38f // per PDF 1.7 spec, Annex C, old value  32767
+#define HPDF_LIMIT_MIN_REAL            -3.4E38f // per PDF 1.7 spec, Annex C, old value -32767

But this was not adopted in the code of HPDF_FToA. In HPDF_FToA there is a

char buf[HPDF_REAL_LEN+1];

with (in pdf_consts.h)

#define HPDF_REAL_LEN 11

Thus using larger values will create output similar to

- - - 420.5 297.5 420.5 c
420.5  -  - c

or even

-.(-*,( -.(-*,( -.(-*,( 0 297.5 0 c
.(-*,( 0 .(-*,( -.(-*,( .(-*,( -.(-*,( c

in the PDF.

I suggest the following patch ¹):

In pdf_consts.h change to

#define HPDF_TMP_BUF_SIZ            1024 // old value 512
#define HPDF_SHORT_BUF_SIZ          32
#define HPDF_REAL_LEN               48  // old value 11

and in hpdf_utils.c replace old HPDF_FToA with

#include <math.h>
char*
HPDF_FToA  (char       *s,
            HPDF_REAL   val,
            char       *eptr)
{
    HPDF_DOUBLE int_val;
    HPDF_DOUBLE fpart_val;
    HPDF_DOUBLE dig;
    char buf[HPDF_REAL_LEN + 1];
    char* sptr = s;
    char* t;
    HPDF_UINT32 i;

    if (val > HPDF_LIMIT_MAX_REAL)
        val = HPDF_LIMIT_MAX_REAL;
    else
    if (val < HPDF_LIMIT_MIN_REAL)
        val = HPDF_LIMIT_MIN_REAL;

    t = buf + HPDF_REAL_LEN;
    *t-- = 0;

    if (val!=0 && val < 0) {
        *s++ = '-';
        val = -val;
    }

    /* separate an integer part and a decimal part. */
    fpart_val = modf(val,&int_val);

    /* process integer part */

   do{
        dig=modf(int_val/10.0,&int_val);
        *t = (char)((char)(dig*10+0.5) + '0');
        t--;
    }while (int_val > 0) ;
    /* copy do destination buffer */
    t++;
    while (s <= eptr && *t != 0)
        *s++ = *t++;

    if(fpart_val!=0.0)
    {
        if(s <= eptr)*s++='.';
        for (i = 0; i < 5; i++)
        {
            fpart_val = modf(fpart_val*10,&int_val);
            if(s <= eptr)*s++ = (char)((char)(int_val+0.5) + '0');
            if(fpart_val==0)
                break;
        }
    }
    *s=0;
    return s;
}

This code works fine for me. Please review it and use it, if you like to

¹) No, I cannot create a pull request due firewall restrictions in my office.

@bramton
Copy link
Member

bramton commented Apr 10, 2023

Thanks, this has been very helpful in fixing #258 .

@bramton bramton closed this as completed Apr 10, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants