diff options
| author | David Mathog <mathog@caltech.edu> | 2014-03-26 20:36:31 +0000 |
|---|---|---|
| committer | Markus Engel <markus.engel@tum.de> | 2014-03-26 20:36:31 +0000 |
| commit | 9e0bf17c455a81983aeedb26203cfb80442bc630 (patch) | |
| tree | 5a5ab17b8f4ea87dc64e401daf1104755a6ce6b6 /src | |
| parent | Remove Snap menu item and improve grid menu item text (diff) | |
| download | inkscape-9e0bf17c455a81983aeedb26203cfb80442bc630.tar.gz inkscape-9e0bf17c455a81983aeedb26203cfb80442bc630.zip | |
Second patch for analyzer warnings in libuemf.
(bzr r13214)
Diffstat (limited to 'src')
| -rw-r--r-- | src/extension/internal/text_reassemble.c | 39 | ||||
| -rw-r--r-- | src/libuemf/uemf_utf.c | 292 | ||||
| -rw-r--r-- | src/libuemf/upmf.c | 213 | ||||
| -rw-r--r-- | src/libuemf/upmf.h | 2 | ||||
| -rw-r--r-- | src/libuemf/uwmf.c | 2 |
5 files changed, 355 insertions, 193 deletions
diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c index c62c83120..810e3f8cc 100644 --- a/src/extension/internal/text_reassemble.c +++ b/src/extension/internal/text_reassemble.c @@ -67,8 +67,8 @@ Optional compiler switches for development: File: text_reassemble.c -Version: 0.0.13 -Date: 24-MAR-2014 +Version: 0.0.14 +Date: 25-MAR-2014 Author: David Mathog, Biology Division, Caltech email: mathog@caltech.edu Copyright: 2014 David Mathog and California Institute of Technology (Caltech) @@ -601,10 +601,13 @@ FT_INFO *ftinfo_init(void){ */ int ftinfo_make_insertable(FT_INFO *fti){ int status=0; + FNT_SPECS *tmp; if(!fti)return(2); if(fti->used >= fti->space){ fti->space += ALLOCINFO_CHUNK; - if((fti->fonts = (FNT_SPECS *) realloc(fti->fonts, fti->space * sizeof(FNT_SPECS) ))){ + tmp = (FNT_SPECS *) realloc(fti->fonts, fti->space * sizeof(FNT_SPECS) ); + if(tmp){ + fti->fonts = tmp; memset(&fti->fonts[fti->used],0,(fti->space - fti->used)*sizeof(FNT_SPECS)); } else { @@ -844,10 +847,13 @@ void ftinfo_dump(const FT_INFO *fti){ */ int fsp_alts_make_insertable(FNT_SPECS *fsp){ int status=0; + ALT_SPECS *tmp; if(!fsp)return(2); if(fsp->used >= fsp->space){ fsp->space += ALLOCINFO_CHUNK; - if((fsp->alts = (ALT_SPECS *) realloc(fsp->alts, fsp->space * sizeof(ALT_SPECS) ))){ + tmp = (ALT_SPECS *) realloc(fsp->alts, fsp->space * sizeof(ALT_SPECS) ); + if(tmp){ + fsp->alts = tmp; memset(&fsp->alts[fsp->used],0,(fsp->space - fsp->used)*sizeof(ALT_SPECS)); } else { @@ -912,10 +918,13 @@ int fsp_alts_weight(FNT_SPECS *fsp, uint32_t a_idx){ */ int csp_make_insertable(CHILD_SPECS *csp){ int status=0; + int *tmp; if(!csp)return(2); if(csp->used >= csp->space){ csp->space += ALLOCINFO_CHUNK; - if((csp->members = (int *) realloc(csp->members, csp->space * sizeof(int) ))){ + tmp = (int *) realloc(csp->members, csp->space * sizeof(int) ); + if(tmp){ + csp->members = tmp; memset(&csp->members[csp->used],0,(csp->space - csp->used)*sizeof(int)); } else { @@ -1007,9 +1016,12 @@ CX_INFO *cxinfo_init(void){ */ int cxinfo_make_insertable(CX_INFO *cxi){ int status=0; + CX_SPECS *tmp; if(cxi->used >= cxi->space){ cxi->space += ALLOCINFO_CHUNK; - if((cxi->cx = (CX_SPECS *) realloc(cxi->cx, cxi->space * sizeof(CX_SPECS) ))){ + tmp = (CX_SPECS *) realloc(cxi->cx, cxi->space * sizeof(CX_SPECS) ); + if(tmp){ + cxi->cx = tmp; memset(&cxi->cx[cxi->used],0,(cxi->space - cxi->used)*sizeof(CX_SPECS)); } else { @@ -1178,9 +1190,12 @@ TP_INFO *tpinfo_init(void){ */ int tpinfo_make_insertable(TP_INFO *tpi){ int status=0; + TCHUNK_SPECS *tmp; if(tpi->used >= tpi->space){ tpi->space += ALLOCINFO_CHUNK; - if((tpi->chunks = (TCHUNK_SPECS *) realloc(tpi->chunks, tpi->space * sizeof(TCHUNK_SPECS) ))){ + tmp = (TCHUNK_SPECS *) realloc(tpi->chunks, tpi->space * sizeof(TCHUNK_SPECS) ); + if(tmp){ + tpi->chunks = tmp; memset(&tpi->chunks[tpi->used],0,(tpi->space - tpi->used)*sizeof(TCHUNK_SPECS)); } else { @@ -1251,10 +1266,13 @@ BR_INFO *brinfo_init(void){ */ int brinfo_make_insertable(BR_INFO *bri){ int status=0; + BRECT_SPECS *tmp; if(!bri)return(2); if(bri->used >= bri->space){ bri->space += ALLOCINFO_CHUNK; - if(!(bri->rects = (BRECT_SPECS *) realloc(bri->rects, bri->space * sizeof(BRECT_SPECS) ))){ status = 1; } + tmp = (BRECT_SPECS *) realloc(bri->rects, bri->space * sizeof(BRECT_SPECS) ); + if(tmp){ bri->rects = tmp; } + else { status = 1;} } return(status); } @@ -1680,11 +1698,14 @@ int trinfo_load_ft_opts(TR_INFO *tri, int use_kern, int load_flags, int kern_mod */ int trinfo_append_out(TR_INFO *tri, const char *src){ size_t slen; + uint8_t *tmp; if(!src)return(-1); slen = strlen(src); if(tri->outused + (int) slen + 1 >= tri->outspace){ tri->outspace += TEREMAX(ALLOCOUT_CHUNK,slen+1); - if(!(tri->out = realloc(tri->out, tri->outspace )))return(-1); + tmp = realloc(tri->out, tri->outspace * sizeof(uint8_t) ); + if(tmp){ tri->out = tmp; } + else { return(-1); } } memcpy(tri->out + tri->outused, src, slen+1); /* copy the terminator */ tri->outused += slen; /* do not count the terminator in the length */ diff --git a/src/libuemf/uemf_utf.c b/src/libuemf/uemf_utf.c index 0159d51cd..5c6507818 100644 --- a/src/libuemf/uemf_utf.c +++ b/src/libuemf/uemf_utf.c @@ -227,6 +227,7 @@ uint16_t *U_Utf32leToUtf16le( size_t *len ){ char *dst,*dst2; + char *src2 = (char *) src; size_t srclen,dstlen,status; if(!src)return(NULL); @@ -235,16 +236,23 @@ uint16_t *U_Utf32leToUtf16le( dstlen = 2 + srclen; // this will always work, but may waste space dst2 = dst = calloc(dstlen,1); // so there will be at least one terminator - if(!dst)return(NULL); - iconv_t conv = iconv_open("UTF-16LE", "UTF-32LE"); - status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status == (size_t) -1){ - free(dst2); - dst2 = NULL; - } - else if(len){ - *len=wchar16len((uint16_t *)dst2); + if(dst){ + iconv_t conv = iconv_open("UTF-16LE", "UTF-32LE"); + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=wchar16len((uint16_t *)dst2); + } + } } return((uint16_t *)dst2); } @@ -270,17 +278,23 @@ uint32_t *U_Utf16leToUtf32le( else { srclen = 2*wchar16len(src)+2; } // include terminator, length in BYTES dstlen = 2*(2 + srclen); // This should always work dst2 = dst = calloc(dstlen,1); - if(!dst)return(NULL); - iconv_t conv = iconv_open("UTF-32LE", "UTF-16LE"); - if ( conv == (iconv_t)-1)return(NULL); - status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status == (size_t) -1){ - free(dst2); - dst2 = NULL; - } - else if(len){ - *len=wchar32len((uint32_t *)dst2); + if(dst){ + iconv_t conv = iconv_open("UTF-32LE", "UTF-16LE"); + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=wchar32len((uint32_t *)dst2); + } + } } return((uint32_t *) dst2); } @@ -312,17 +326,23 @@ uint32_t *U_Latin1ToUtf32le( else { srclen = strlen(src)+1; } // include terminator, length in BYTES dstlen = sizeof(uint32_t)*(1 + srclen); // This should always work but might waste some space dst2 = dst = calloc(dstlen,1); - if(!dst)return(NULL); - iconv_t conv = iconv_open("UTF-32LE", "LATIN1"); - if ( conv == (iconv_t) -1)return(NULL); - status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status == (size_t) -1){ - free(dst2); - dst2 = NULL; - } - else if(len){ - *len=wchar32len((uint32_t *)dst2); + if(dst){ + iconv_t conv = iconv_open("UTF-32LE", "LATIN1"); + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=wchar32len((uint32_t *)dst2); + } + } } return((uint32_t *) dst2); } @@ -348,17 +368,23 @@ uint32_t *U_Utf8ToUtf32le( else { srclen = strlen(src)+1; } // include terminator, length in BYTES dstlen = sizeof(uint32_t)*(1 + srclen); // This should always work but might waste some space dst2 = dst = calloc(dstlen,1); - if(!dst)return(NULL); - iconv_t conv = iconv_open("UTF-32LE", "UTF-8"); - if ( conv == (iconv_t) -1)return(NULL); - status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status == (size_t) -1){ - free(dst2); - dst2 = NULL; - } - else if(len){ - *len=wchar32len((uint32_t *)dst2); + if(dst){ + iconv_t conv = iconv_open("UTF-32LE", "UTF-8"); + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=wchar32len((uint32_t *)dst2); + } + } } return((uint32_t *) dst2); } @@ -384,17 +410,23 @@ char *U_Utf32leToUtf8( else { srclen = 4*(1 + wchar32len(src)); } //include terminator, length in BYTES dstlen = 1 + srclen; // This should always work but might waste some space dst2 = dst = calloc(dstlen,1); - if(!dst)return(NULL); - iconv_t conv = iconv_open("UTF-8", "UTF-32LE"); - if ( conv == (iconv_t)-1)return(NULL); - status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status == (size_t) -1){ - free(dst2); - dst2 = NULL; - } - else if(len){ - *len=strlen(dst2); + if(dst){ + iconv_t conv = iconv_open("UTF-8", "UTF-32LE"); + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=strlen(dst2); + } + } } return(dst2); } @@ -412,25 +444,31 @@ uint16_t *U_Utf8ToUtf16le( size_t *len ){ char *dst,*dst2; + char *src2 = (char *) src; size_t srclen,dstlen,status; - iconv_t conv; if(!src)return(NULL); if(max){ srclen = max; } else { srclen = strlen(src)+1; } // include terminator, length in BYTES dstlen = 2 * (1 + srclen); // this will always work, but may waste space dst2 = dst =calloc(dstlen,1); // so there will always be a terminator - if(!dst)return(NULL); - conv = iconv_open("UTF-16LE", "UTF-8"); - if (conv == (iconv_t) -1)return(NULL); - status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status == (size_t) -1){ - free(dst2); - dst2 = NULL; - } - else if(len){ - *len=wchar16len((uint16_t *)dst2); + if(dst){ + iconv_t conv = iconv_open("UTF-16LE", "UTF-8"); + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=wchar16len((uint16_t *)dst2); + } + } } return((uint16_t *)dst2); } @@ -448,7 +486,7 @@ char *U_Utf16leToUtf8( size_t *len ){ char *dst, *dst2; - char *ret=NULL; + char *src2 = (char *) src; size_t srclen,dstlen,status; if(!src)return(NULL); @@ -457,16 +495,28 @@ char *U_Utf16leToUtf8( dstlen = 1 + 2*srclen; // this will always work, but may waste space // worst case is all glyphs (==max) need 4 UTF-8 encoded bytes + terminator. dst2 = dst = (char *) calloc(dstlen,1); - if(!dst)return(NULL); - iconv_t conv = iconv_open("UTF-8", "UTF-16LE"); - status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status != (size_t) -1){ - if(len)*len=strlen(dst2); - ret=U_strdup(dst2); // make a string of exactly the right size + if(dst){ + iconv_t conv = iconv_open("UTF-8", "UTF-16LE"); + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=strlen(dst2); + dst = dst2; + dst2 = U_strdup(dst); // make a string of exactly the right size + free(dst); // free the one which was probably too big + } + } } - free(dst2); // free the one which was probably too big - return(ret); + return(dst2); } /** @@ -482,22 +532,36 @@ char *U_Utf16leToLatin1( size_t *len ){ char *dst, *dst2; - char *ret=NULL; + char *src2 = (char *) src; size_t srclen,dstlen,status; if(!src)return(NULL); if(max){ srclen = 2*max; } else { srclen = 2*(1 +wchar16len(src)); } //include terminator, length in BYTES dstlen = 1 + srclen; // this will always work as latin1 is always 1 byte/character - ret = dst2 = dst = (char *) calloc(dstlen,1); - if(!dst)return(NULL); - iconv_t conv = iconv_open("LATIN1//TRANSLIT", "UTF-16LE"); // translate what can be, fill in with something close for the rest - status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status != (size_t) -1){ - if(len)*len=strlen(dst2); + dst2 = dst = (char *) calloc(dstlen,1); + if(dst){ + iconv_t conv = iconv_open("LATIN1//TRANSLIT", "UTF-16LE"); + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=strlen(dst2); + dst = dst2; + dst2 = U_strdup(dst); // make a string of exactly the right size + free(dst); // free the one which was probably too big + } + } } - return(ret); + return(dst2); } /** \brief Put a single 16 bit character into UTF-16LE form. @@ -534,22 +598,29 @@ char *U_Utf8ToLatin1( size_t *len ){ char *dst,*dst2; + char *src2 = (char *) src; size_t srclen,dstlen,status; if(max){ srclen = max; } else { srclen = strlen(src)+1; } // include terminator, length in BYTES dstlen = (1 + srclen); // This should always work but might waste some space dst2 = dst = calloc(dstlen,1); - if(!dst)return(NULL); - iconv_t conv = iconv_open("LATIN1//TRANSLIT", "UTF-8"); // translate what can be, fill in with something close for the rest - if ( conv == (iconv_t) -1)return(NULL); - status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status == (size_t) -1){ - free(dst2); - dst2 = NULL; - } - else if(len){ - *len=strlen(dst2); + if(dst){ + iconv_t conv = iconv_open("LATIN1//TRANSLIT", "UTF-8"); // translate what can be, fill in with something close for the rest + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=strlen(dst2); + } + } } return((char *) dst2); } @@ -571,22 +642,29 @@ char *U_Latin1ToUtf8( size_t *len ){ char *dst,*dst2; + char *src2 = (char *) src; size_t srclen,dstlen,status; if(max){ srclen = max; } else { srclen = strlen(src)+1; } // include terminator, will waste some space dstlen = (1 + 2*srclen); // This should always work because all latin1 convert to 1 or 2 byte UTF8, it might waste some space dst2 = dst = calloc(dstlen,1); - if(!dst)return(NULL); - iconv_t conv = iconv_open("UTF-8", "LATIN1"); // everything should translate - if ( conv == (iconv_t) -1)return(NULL); - status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen); - iconv_close(conv); - if(status == (size_t) -1){ - free(dst2); - dst2 = NULL; - } - else if(len){ - *len=strlen(dst2); + if(dst){ + iconv_t conv = iconv_open("UTF-8", "LATIN1"); // everything should translate + if ( conv == (iconv_t) -1){ + free(dst2); + dst2=NULL; + } + else { + status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen); + iconv_close(conv); + if(status == (size_t) -1){ + free(dst2); + dst2 = NULL; + } + else if(len){ + *len=strlen(dst2); + } + } } return((char *) dst2); } diff --git a/src/libuemf/upmf.c b/src/libuemf/upmf.c index a7a5e42b5..0b7204635 100644 --- a/src/libuemf/upmf.c +++ b/src/libuemf/upmf.c @@ -70,18 +70,25 @@ void U_swap4(void *ul, unsigned int count); /** \brief Utility function for writing one or more EMF+ records in a PseudoObject to the EMF output file - \param po U_PSEUDO_OBJ to write + \return 1 on success, 0 on error. + \param po U_PSEUDO_OBJ to write, it is deleted after it is written \param sum U_PSEUDO_OBJ to use for scratch space \param et EMFTRACK used to write records to EMF file */ -void U_PMR_write(U_PSEUDO_OBJ *po, U_PSEUDO_OBJ *sum, EMFTRACK *et){ +int U_PMR_write(U_PSEUDO_OBJ *po, U_PSEUDO_OBJ *sum, EMFTRACK *et){ char *rec; + int status = 0; sum->Used = 0; /* clean it out, retaining allocated memory */ sum = U_PO_append(sum, "EMF+", 4); /* indicates that this comment holds an EMF+ record */ + if(!sum)goto end; sum = U_PO_append(sum, po->Data, po->Used); /* the EMF+ record itself */ + if(!sum)goto end; + U_PO_free(&po); /* delete the PseudoObject */ rec = U_EMRCOMMENT_set(sum->Used, sum->Data); /* stuff it into the EMF comment */ - (void) emf_append((PU_ENHMETARECORD)rec, et, 1); /* write it to the EMF file */ - U_PO_free(&po); /* delete the PseudoObjects */ + if(!emf_append((PU_ENHMETARECORD)rec, et, 1))goto end; /* write it to the EMF file, delete the record, check status */ + status = 1; +end: + return(status); } /** @@ -442,8 +449,12 @@ int U_OA_append(U_OBJ_ACCUM *oa, const char *data, int size, int Type, int Id){ tail = oa->used; if(oa->used + size >= oa->space){ oa->space += size; - oa->accum = (char *) realloc(oa->accum, oa->space); - if(!oa->accum)return(1); + char *newaccum = (char *) realloc(oa->accum, oa->space); + if(!newaccum){ + oa->space -= size; /* put it back the way it was */ + return(1); + } + oa->accum = newaccum; } memcpy(oa->accum + tail,data,size); oa->used += size; @@ -525,19 +536,22 @@ U_PSEUDO_OBJ *U_PO_create(char *Data, size_t Size, size_t Use, uint32_t Type){ U_PSEUDO_OBJ *U_PO_append(U_PSEUDO_OBJ *po, const char *Data, size_t Size){ /* po cannot be NULL,as in U_PO_po_append(), because there would be no way to determine the TYPE of the resulting PO */ if(po){ - if(po->Used + Size > po->Size){ + if(!po->Data || po->Used + Size > po->Size){ po->Size = po->Used + Size; - po->Data = realloc(po->Data, po->Size); + char *newData = realloc(po->Data, po->Size); + if(!newData){ + po->Size -= Size; /* put it back the way it was*/ + po=NULL; /* skip the rest of the actions, does not affect po in caller */ + } + else { + po->Data = newData; + } } - if(po->Data){ + if(po){ /* po->Data ready to append new data */ if(Data){ memcpy(po->Data + po->Used, Data, Size); } else { memset(po->Data + po->Used, 0, Size); } po->Used += Size; } - if(!po->Data){ - free(po); - po=NULL; - } } return(po); } @@ -551,33 +565,35 @@ U_PSEUDO_OBJ *U_PO_append(U_PSEUDO_OBJ *po, const char *Data, size_t Size){ */ U_PSEUDO_OBJ *U_PO_po_append(U_PSEUDO_OBJ *po, U_PSEUDO_OBJ *Src, int StripE){ if(!Src){ return(NULL); } + if((StripE && (Src->Used == 4)) || !Src->Used){ return(po); } /* appending nothing is not an error */ char *Data = Src->Data; - size_t Size = Src->Size; + size_t Size = Src->Used; /* append only what is used */ + U_PSEUDO_OBJ *ipo = po; if(StripE){ Size -= 4; } - if(!po){ - po = U_PO_create(NULL, 0, 0, Src->Type); /* create an empty pseudoobject */ + if(!ipo){ + ipo = U_PO_create(NULL, 0, 0, Src->Type); /* create an empty pseudoobject */ } - if(po){ - if(po->Data){ - if(po->Used + Size > po->Size){ - po->Size = po->Used + Size; - po->Data = realloc(po->Data, po->Size); + if(ipo){ + if(!ipo->Data || ipo->Used + Size > ipo->Size){ + ipo->Size = ipo->Used + Size; + char *newData = realloc(ipo->Data, ipo->Size); + if(!newData){ + if(ipo != po)U_PO_free(&ipo); } - if(po->Data){ - if(Data){ - if(StripE){ memcpy(po->Data + po->Used, Data + 4, Size); } /* Size is already 4 less, skip the leading Elements value */ - else { memcpy(po->Data + po->Used, Data, Size); } /* copy everything */ - } - else { memset(po->Data + po->Used, 0, Size); } /* set everything */ - po->Used += Size; + else { + ipo->Data = newData; } } - if(!po->Data){ - free(po); - po=NULL; + if(ipo){ + if(Data){ + if(StripE){ memcpy(ipo->Data + ipo->Used, Data + 4, Size); } /* Size is already 4 less, skip the leading Elements value */ + else { memcpy(ipo->Data + ipo->Used, Data, Size); } /* copy everything */ + } + else { memset(ipo->Data + ipo->Used, 0, Size); } /* set everything */ + ipo->Used += Size; } } - return(po); + return(ipo); } /** @@ -672,7 +688,7 @@ U_DPSEUDO_OBJ *U_PATH_create(int Elements, const U_PMF_POINTF *Points, uint8_t F if(!(Others & U_PPT_Bezier)){ return(NULL); } /* will pass if either line or bezier is set */ } - U_DPSEUDO_OBJ *Path = (U_DPSEUDO_OBJ *)malloc(sizeof(U_DPSEUDO_OBJ)); + U_DPSEUDO_OBJ *Path = (U_DPSEUDO_OBJ *)calloc(sizeof(U_DPSEUDO_OBJ),1); /* make poTypes and poPoints NULL */ const U_SERIAL_DESC List[] = { {NULL,0,0,U_XX} }; if(Path){ Path->Elements = Elements; @@ -733,17 +749,23 @@ int U_DPO_clear(U_DPSEUDO_OBJ *dpo){ int U_PATH_moveto(U_DPSEUDO_OBJ *Path, U_PMF_POINTF Point, uint8_t Flags){ if(!Path){ return(0); } U_PSEUDO_OBJ *tpo; + U_PSEUDO_OBJ *tpo2; uint8_t Type = (Flags & U_PTP_NotClose) | U_PPT_Start; tpo = U_PMF_POINTF_set(1, &Point); if(!tpo){ return(0); } - Path->poPoints = U_PO_po_append(Path->poPoints, tpo, U_PMF_DROP_ELEMENTS); + tpo2 = U_PO_po_append(Path->poPoints, tpo, U_PMF_DROP_ELEMENTS); U_PO_free(&tpo); + if(!tpo2)return(0); + Path->poPoints = tpo2; + tpo = U_PMF_PATHPOINTTYPE_set(1, &Type); if(!tpo){ return(0); } - Path->poTypes = U_PO_po_append(Path->poTypes, tpo, U_PMF_DROP_ELEMENTS); + tpo2= U_PO_po_append(Path->poTypes, tpo, U_PMF_DROP_ELEMENTS); U_PO_free(&tpo); + if(!tpo2)return(0); + Path->poTypes = tpo2; Path->Elements++; return(1); @@ -760,16 +782,22 @@ int U_PATH_lineto(U_DPSEUDO_OBJ *Path, U_PMF_POINTF Point, uint8_t Flags){ if(!Path || !Path->Elements){ return(0); } /* must be at least one point to extend from */ if(Path->poTypes->Data[Path->Elements - 1] & U_PTP_CloseSubpath){ return(0); } /* cannot extend a closed subpath */ U_PSEUDO_OBJ *tpo; + U_PSEUDO_OBJ *tpo2; uint8_t Type = (Flags & U_PTP_NotClose) | U_PPT_Line; tpo = U_PMF_POINTF_set(1, &Point); if(!tpo){ return(0); } - Path->poPoints = U_PO_po_append(Path->poPoints, tpo, U_PMF_DROP_ELEMENTS); + tpo2 = U_PO_po_append(Path->poPoints, tpo, U_PMF_DROP_ELEMENTS); U_PO_free(&tpo); + if(!tpo2)return(0); + Path->poPoints = tpo2; + tpo = U_PMF_PATHPOINTTYPE_set(1, &Type); if(!tpo){ return(0); } - Path->poTypes = U_PO_po_append(Path->poTypes, tpo, U_PMF_DROP_ELEMENTS); + tpo2 = U_PO_po_append(Path->poTypes, tpo, U_PMF_DROP_ELEMENTS); U_PO_free(&tpo); + if(!tpo2)return(0); + Path->poTypes = tpo2; Path->Elements++; return(1); @@ -802,18 +830,24 @@ int U_PATH_polylineto(U_DPSEUDO_OBJ *Path, uint32_t Elements, const U_PMF_POINTF if(!Path || !Points){ return(0); } if(!Elements){ return(1); } /* harmless - do nothing */ U_PSEUDO_OBJ *tpo; + U_PSEUDO_OBJ *tpo2; uint8_t First, Others; tpo = U_PMF_POINTF_set(Elements, Points); - Path->poPoints = U_PO_po_append(Path->poPoints, tpo, U_PMF_DROP_ELEMENTS); + tpo2 = U_PO_po_append(Path->poPoints, tpo, U_PMF_DROP_ELEMENTS); U_PO_free(&tpo); + if(!tpo2)return(0); + Path->poPoints = tpo2; + if(StartSeg){ First = (Flags & U_PTP_NotClose) | U_PPT_Start; } else { First = (Flags & U_PTP_NotClose) | U_PPT_Line; } Others = (Flags & U_PTP_NotClose) | U_PPT_Line; tpo = U_PMF_PATHPOINTTYPE_set2(Elements, First, Others); if(!tpo){ return(0); } - Path->poTypes = U_PO_po_append(Path->poTypes, tpo, U_PMF_DROP_ELEMENTS); + tpo2 = U_PO_po_append(Path->poTypes, tpo, U_PMF_DROP_ELEMENTS); U_PO_free(&tpo); + if(!tpo2)return(0); + Path->poTypes = tpo2; Path->Elements += Elements; return(1); @@ -842,19 +876,24 @@ int U_PATH_polybezierto(U_DPSEUDO_OBJ *Path, uint32_t Elements, const U_PMF_POIN if(StartSeg && ((Elements - 1) % 3)){ return(0); } /* new segment must be 1 + N*3 points */ if(!StartSeg && (Elements % 3)){ return(0); } /* extend segment must be N*3 points */ U_PSEUDO_OBJ *tpo; + U_PSEUDO_OBJ *tpo2; uint8_t First, Others; tpo = U_PMF_POINTF_set(Elements, Points); - Path->poPoints = U_PO_po_append(Path->poPoints, tpo, U_PMF_DROP_ELEMENTS); + tpo2 = U_PO_po_append(Path->poPoints, tpo, U_PMF_DROP_ELEMENTS); U_PO_free(&tpo); + if(!tpo2)return(0); + Path->poPoints = tpo2; if(StartSeg){ First = (Flags & U_PTP_NotClose) | U_PPT_Start; } else { First = (Flags & U_PTP_NotClose) | U_PPT_Bezier; } Others = (Flags & U_PTP_NotClose) | U_PPT_Bezier; tpo = U_PMF_PATHPOINTTYPE_set2(Elements, First, Others); if(!tpo){ return(0); } - Path->poTypes = U_PO_po_append(Path->poTypes, tpo, U_PMF_DROP_ELEMENTS); + tpo2 = U_PO_po_append(Path->poTypes, tpo, U_PMF_DROP_ELEMENTS); U_PO_free(&tpo); + if(!tpo2)return(0); + Path->poTypes = tpo2; Path->Elements += Elements; return(1); @@ -2856,23 +2895,28 @@ U_PSEUDO_OBJ *U_PMF_PATHPOINTTYPERLE_set(uint32_t Elements, const uint8_t *Bz, c if(!Bz || !RL || !Ppte)return(NULL); /* allocate space in the structure but put no data in */ U_PSEUDO_OBJ *po = U_PO_create(NULL, 4 + 2*Elements, 0, U_PMF_PATHPOINTTYPERLE_OID | U_PMF_ARRAY_OID); - - U_PSEUDO_OBJ *poi = U_PMF_4NUM_set(Elements); - po = U_PO_append(po, poi->Data, poi->Used); - U_PO_free(&poi); - + U_PSEUDO_OBJ *holdpo = po; if(po){ + U_PSEUDO_OBJ *poi = U_PMF_4NUM_set(Elements); + if(!poi)goto end; + po = U_PO_append(po, poi->Data, poi->Used); + U_PO_free(&poi); + if(!po)goto end; + for( ;Elements; Elements--, Bz++, RL++, Ppte++){ po = U_PO_append(po, (char *)Ppte, 1); - if(*RL > 0x3F){ /* run length too big for field */ - U_PO_free(&po); - return(NULL); - } + if(!po)goto end; + + if(*RL > 0x3F) goto end; /* run length too big for field */ + utmp = (*Bz ? 1 : 0) | ((*RL & 0x3F)<<2); /* bit 1 is not used and is set to 0 */ po = U_PO_append(po, (char *)&utmp, 1); + if(!po)goto end; } } - return(po); +end: + if(!po)U_PO_free(&holdpo); + return(holdpo); } /** @@ -3007,10 +3051,13 @@ U_PSEUDO_OBJ *U_PMF_POINTR_set(uint32_t Elements, const U_PMF_POINTF *Coords){ U_PSEUDO_OBJ *poi; /* Worst case scenario it is 4 bytes per coord, plus the count */ U_PSEUDO_OBJ *po = U_PO_create(NULL, 4 + 4*Elements, 0, U_PMF_POINTR_OID); /* not exactly an array, so no U_PMF_ARRAY_OID */ + U_PSEUDO_OBJ *holdpo = po; + if(!po)goto end; poi = U_PMF_4NUM_set(Elements); po = U_PO_append(po, poi->Data, poi->Used); U_PO_free(&poi); + if(po)goto end; for(Xf = Yf = 0.0 ;Elements; Elements--, Coords++){ Xf = U_ROUND(Coords->X) - Xf; @@ -3026,27 +3073,27 @@ U_PSEUDO_OBJ *U_PMF_POINTR_set(uint32_t Elements, const U_PMF_POINTF *Coords){ if(!poi)poi = U_PMF_INTEGER15_set(X); /* This one must work because of the range checking, above */ po = U_PO_append(po, poi->Data, poi->Used); U_PO_free(&poi); + if(!po)goto end; poi = U_PMF_INTEGER7_set(Y); if(!poi)poi = U_PMF_INTEGER15_set(Y); /* This one must work because of the range checking, above */ po = U_PO_append(po, poi->Data, poi->Used); U_PO_free(&poi); + if(!po)goto end; } /* Because the values stored were some unpredictable combination of 1 and 2 bytes, the last byte may not end on a 4 byte boundary. Make it do so by padding with up to 3 zero bytes. */ -#if 1 + int residual; - unsigned long int us, uu; - us = po->Size; /* printing size_t portably is a pain, this avoids the issue */ - uu = po->Used; residual = 3 & po->Used; -printf("DEBUG Used:%lu residual:%d\n",uu, residual);fflush(stdout); if(residual){ - po = U_PO_append(po, NULL, (4 - residual)); + po = U_PO_append(po, NULL, (4 - residual)); + if(!po)goto end; } -printf("DEBUG Size:%lu Used:%lu \n",us,uu);fflush(stdout); -#endif - return(po); + +end: + if(!po)U_PO_free(&holdpo); + return(holdpo); } /** @@ -4714,22 +4761,29 @@ U_PSEUDO_OBJ *U_PMR_OBJECT_set(uint32_t ObjID, int otype, int ntype, uint32_t TS int Pad = UP4(TSize) - TSize; if((otype < U_OT_Brush) || (otype > U_OT_CustomLineCap)){ return(NULL); } if(ntype && (cbData > U_OBJRECLIM)){ return(NULL); } - if(!Data){ return(NULL); } + if(!Data || !cbData){ return(NULL); } U_PSEUDO_OBJ *po; if(!ntype && !TSize && (cbData > U_OBJRECLIM)){ ntype = 1; TSize = cbData; po = U_PO_create(NULL, TSize + 16 * (1 + (TSize/cbData)), 0, U_PMR_OBJECT_OID); - if(!po)return(po); - while(cbData){ - CSize = (cbData > U_OBJRECLIM ? U_OBJRECLIM : cbData); - U_PSEUDO_OBJ *pot = U_PMR_OBJECT_set(ObjID, otype, ntype, TSize, CSize, Data); - po = U_PO_po_append(po, pot, U_PMF_KEEP_ELEMENTS); - U_PO_free(&pot); - Data += U_OBJRECLIM; - cbData -= CSize; - } + if(po){ + while(cbData){ + CSize = (cbData > U_OBJRECLIM ? U_OBJRECLIM : cbData); + U_PSEUDO_OBJ *pot = U_PMR_OBJECT_set(ObjID, otype, ntype, TSize, CSize, Data); + if(!pot)break; + U_PSEUDO_OBJ *newpo = U_PO_po_append(po, pot, U_PMF_KEEP_ELEMENTS); + U_PO_free(&pot); + if(!newpo)break; + po = newpo; + Data += U_OBJRECLIM; + cbData -= CSize; + } + if(cbData){ /* some error */ + U_PO_free(&po); + } + } } else { /* Send in DataSize, U_PMR_CMN_HDR_set will adjust Header Size with 1-3 pad bytes if needed */ @@ -6280,22 +6334,24 @@ int U_PMF_POINTR_get(const char **contents, U_FLOAT *X, U_FLOAT *Y){ \param Points Caller must free. Array of U_PMF_POINTF coordinates. */ int U_PMF_VARPOINTS_get(const char **contents, uint16_t Flags, int Elements, U_PMF_POINTF **Points){ - if(!contents || !*contents || !Points || !Elements){ return(0); } + int status = 0; + if(!contents || !*contents || !Points || !Elements){ return(status); } U_PMF_POINTF *pts = (U_PMF_POINTF *)malloc(Elements * sizeof(U_PMF_POINTF)); + if(!pts){ return(status); } + *Points = pts; U_FLOAT XF, YF; U_FLOAT XFS, YFS; - *Points = pts; for(XFS = YFS = 0.0; Elements; Elements--, pts++){ if(Flags & U_PPF_P){ - U_PMF_POINTR_get(contents, &XF, &YF); + if(!U_PMF_POINTR_get(contents, &XF, &YF))break; /* this should never happen */ XFS += XF; /* position relative to previous point, first point is always 0,0 */ YFS += YF; pts->X = XFS; pts->Y = YFS; } else if(Flags & U_PPF_C){ - (void) U_PMF_POINT_get(contents, &XF, &XF); + if(!U_PMF_POINT_get(contents, &XF, &XF))break; /* this should never happen */ pts->X = XF; pts->Y = YF; } @@ -6303,7 +6359,14 @@ int U_PMF_VARPOINTS_get(const char **contents, uint16_t Flags, int Elements, U_P (void) U_PMF_POINTF_get(contents, &(pts->X), &(pts->Y)); } } - return(1); + if(Elements){ /* some error in the preceding */ + free(pts); + *Points = NULL; + } + else { + status = 1; + } + return(status); } /** diff --git a/src/libuemf/upmf.h b/src/libuemf/upmf.h index 48fc9bf53..27ac94a89 100644 --- a/src/libuemf/upmf.h +++ b/src/libuemf/upmf.h @@ -2820,7 +2820,7 @@ typedef struct { //! \cond /* EMF+ prototypes (helper functions) */ -void U_PMR_write(U_PSEUDO_OBJ *po, U_PSEUDO_OBJ *sum, EMFTRACK *et); +int U_PMR_write(U_PSEUDO_OBJ *po, U_PSEUDO_OBJ *sum, EMFTRACK *et); int U_PMR_drawline(uint32_t PenID, uint32_t PathID, U_PMF_POINTF Start, U_PMF_POINTF End, int Dashed, U_PSEUDO_OBJ *sum, EMFTRACK *et); int U_PMR_drawstring( const char *string, int Vpos, uint32_t FontID, const U_PSEUDO_OBJ *BrushID, uint32_t FormatID, U_PMF_STRINGFORMAT Sfs, const char *FontName, U_FLOAT Height, U_FontInfoParams *fip, uint32_t FontFlags, diff --git a/src/libuemf/uwmf.c b/src/libuemf/uwmf.c index 82be9f324..b4a1dfc52 100644 --- a/src/libuemf/uwmf.c +++ b/src/libuemf/uwmf.c @@ -599,7 +599,7 @@ const char *U_wmr_names(int idx){ */ const char *U_wmr_escnames(int idx){ const char *name; - if(idx>=0 && idx <= 0x0023){ + if(idx>=1 && idx <= 0x0023){ switch(idx){ case 0x0001: name = "NEWFRAME"; break; case 0x0002: name = "ABORTDOC"; break; |
