Permalink
Browse files

Fix for crash when making a spiro connection starting near a point in

the y glyph.

Note that the spiro rendering that ensues is not pretty, but fontforge
itself no longer crashes when trying to make this new segment.

The CVMergeSPLS() function is only called in this particular case and
was assuming memory ownership in cv->p.spl which might not have been
true.

I have also used SplinePointCreate() in a few more places so that a
create/free memory trace is a little easier to add in if suspected
double free() action is happening.
  • Loading branch information...
monkeyiq committed Jan 18, 2013
1 parent aea9856 commit 5c92298daa38b0fb81958ac06e1fb8fb2d3507d2
Showing with 16 additions and 12 deletions.
  1. +3 −0 fontforge/baseviews.h
  2. +4 −9 fontforge/cvaddpoints.c
  3. +2 −1 fontforge/splinefont.h
  4. +7 −2 fontforge/splineutil.c
View
@@ -29,6 +29,9 @@
#include "splinefont.h"
+#define free_with_debug(x) { fprintf(stderr,"%p FREE()\n",x); free(x); }
+
+
enum widthtype { wt_width, wt_lbearing, wt_rbearing, wt_bearings, wt_vwidth };
enum fvtrans_flags { fvt_alllayers=1, fvt_round_to_int=2,
View
@@ -304,6 +304,7 @@ static void CVMergeSPLS(CharView *cv,SplineSet *ss, SplinePoint *base,SplinePoin
} else
SplineSetSpirosClear(ss);
cv->p.spl->last = cv->p.spl->first = NULL;
+ cv->p.spl->spiros = 0;
SplinePointListFree(cv->p.spl);
cv->p.spl = NULL;
}
@@ -474,10 +475,7 @@ return; /* We clicked on the active point, that's a no-op */
if ( sp==NULL || (sp->next!=NULL && sp->prev!=NULL) || sp==base ) {
/* Add a new point */
SplineSetSpirosClear(sel);
- sp = chunkalloc(sizeof(SplinePoint));
- sp->me.x = cv->p.cx;
- sp->me.y = cv->p.cy;
- sp->prevcp = sp->nextcp = sp->me;
+ sp = SplinePointCreate( cv->p.cx, cv->p.cy );
sp->noprevcp = sp->nonextcp = 1;
sp->nextcpdef = sp->prevcpdef = 1;
sp->pointtype = ptype;
@@ -558,14 +556,11 @@ return; /* We clicked on the active point, that's a no-op */
ss = cv->p.spl;
} else {
ss = chunkalloc(sizeof(SplineSet));
- sp = chunkalloc(sizeof(SplinePoint));
+ sp = SplinePointCreate( cv->p.cx, cv->p.cy );
+
ss->first = ss->last = sp;
ss->next = cv->b.layerheads[cv->b.drawmode]->splines;
cv->b.layerheads[cv->b.drawmode]->splines = ss;
- sp->me.x = cv->p.cx;
- sp->me.y = cv->p.cy;
- sp->nextcp = sp->me;
- sp->prevcp = sp->me;
sp->nonextcp = sp->noprevcp = 1;
sp->nextcpdef = sp->prevcpdef = 1;
sp->pointtype = ptype;
View
@@ -1106,7 +1106,8 @@ typedef struct spline {
unsigned int leftedge: 1;
unsigned int rightedge: 1;
unsigned int acceptableextrema: 1; /* This spline has extrema, but we don't care */
- SplinePoint *from, *to;
+ SplinePoint *from;
+ SplinePoint *to;
Spline1D splines[2]; /* splines[0] is the x spline, splines[1] is y */
struct linearapprox *approx;
/* Posible optimizations:
View
@@ -243,7 +243,7 @@ void SplinePointFree(SplinePoint *sp) {
void SplinePointMDFree(SplineChar *sc, SplinePoint *sp) {
MinimumDistance *md, *prev, *next;
-
+
if ( sc!=NULL ) {
prev = NULL;
for ( md = sc->md; md!=NULL; md = next ) {
@@ -289,6 +289,7 @@ void SplineSetBeziersClear(SplinePointList *spl) {
if ( spl==NULL )
return;
+
if ( spl->first!=NULL ) {
nonext = spl->first->next==NULL;
first = NULL;
@@ -310,6 +311,7 @@ void SplinePointListFree(SplinePointList *spl) {
if ( spl==NULL )
return;
+
if ( spl->first!=NULL ) {
nonext = spl->first->next==NULL;
first = NULL;
@@ -1276,9 +1278,11 @@ SplinePointList *SplinePointListCopy1(const SplinePointList *spl) {
cur = chunkalloc(sizeof(SplinePointList));
cur->is_clip_path = spl->is_clip_path;
+ cur->spiro_cnt = cur->spiro_max = 0;
+ cur->spiros = 0;
for ( pt=spl->first; ; ) {
- cpt = chunkalloc(sizeof(SplinePoint));
+ cpt = SplinePointCreate( 0, 0 );
*cpt = *pt;
if ( pt->hintmask!=NULL ) {
cpt->hintmask = chunkalloc(sizeof(HintMask));
@@ -1897,6 +1901,7 @@ SplinePointList *SplinePointListSpiroTransform(SplinePointList *base, real trans
int allsel, anysel;
int i;
+
if ( allpoints )
return( SplinePointListTransform(base,transform,tpt_AllPoints));

0 comments on commit 5c92298

Please sign in to comment.