fix segfault when instantiating LCC schematics if sub-schematic attribute translate()s to empty string: draw_string() tries to modify const char * returned from translate(); set more const attributes in function string params to catch more such errors

This commit is contained in:
Stefan Schippers 2020-08-31 02:25:41 +02:00
parent 7ce7654748
commit 6608230df9
8 changed files with 51 additions and 44 deletions

View File

@ -2046,12 +2046,12 @@ void new_polygon(int what) /* 20171115 */
}
#ifdef HAS_CAIRO
int text_bbox(char *str, double xscale, double yscale,
int text_bbox(const char *str, double xscale, double yscale,
int rot, int flip, int hcenter, int vcenter, double x1,double y1, double *rx1, double *ry1,
double *rx2, double *ry2)
{
int c=0;
char *str_ptr;
char *str_ptr, *s = NULL;
double size;
cairo_text_extents_t ext;
cairo_font_extents_t fext;
@ -2069,18 +2069,19 @@ int text_bbox(char *str, double xscale, double yscale,
ww=0.; hh=1.;
c=0;
cairo_lines=1;
str_ptr = str;
while( str && str[c] ) {
if(str[c] == '\n') {
str[c]='\0';
my_strdup2(1158, &s, str);
str_ptr = s;
while( s && s[c] ) {
if(s[c] == '\n') {
s[c]='\0';
hh++;
cairo_lines++;
if(str_ptr[0]!='\0') {
cairo_text_extents(ctx, str_ptr, &ext);
if(ext.x_advance > ww) ww= ext.x_advance;
}
str[c]='\n';
str_ptr = str+c+1;
s[c]='\n';
str_ptr = s+c+1;
} else {
}
c++;
@ -2089,6 +2090,7 @@ int text_bbox(char *str, double xscale, double yscale,
cairo_text_extents(ctx, str_ptr, &ext);
if(ext.x_advance > ww) ww= ext.x_advance;
}
my_free(1159, &s);
hh = hh*fext.height*cairo_font_line_spacing;
cairo_longest_line = ww;
@ -2125,11 +2127,11 @@ int text_bbox(char *str, double xscale, double yscale,
RECTORDER((*rx1),(*ry1),(*rx2),(*ry2));
return 1;
}
int text_bbox_nocairo(char * str,double xscale, double yscale,
int text_bbox_nocairo(const char * str,double xscale, double yscale,
int rot, int flip, int hcenter, int vcenter, double x1,double y1, double *rx1, double *ry1,
double *rx2, double *ry2)
#else
int text_bbox(char * str,double xscale, double yscale,
int text_bbox(const char * str,double xscale, double yscale,
int rot, int flip, int hcenter, int vcenter, double x1,double y1, double *rx1, double *ry1,
double *rx2, double *ry2)
#endif

View File

@ -288,10 +288,10 @@ void cairo_draw_string_line(cairo_t *ctx, char *s,
}
/* CAIRO version */
void draw_string(int layer, int what, char *s, int rot, int flip, int hcenter, int vcenter,
void draw_string(int layer, int what, const char *s, int rot, int flip, int hcenter, int vcenter,
double x, double y, double xscale, double yscale)
{
char *tt, *ss;
char *tt, *ss, *sss=NULL;
char c;
int lineno=0;
double size;
@ -343,9 +343,9 @@ void draw_string(int layer, int what, char *s, int rot, int flip, int hcenter, i
cairo_set_font_size (ctx, size*mooz);
cairo_set_font_size (save_ctx, size*mooz);
cairo_font_extents(ctx, &fext);
/*fprintf(errfp, "cairo_draw_string(): s=%s lines=%d\n", s, cairo_lines); */
llength=0;
tt=ss=s;
my_strdup2(73, &sss, s);
tt=ss=sss;
for(;;) {
c=*ss;
if(c=='\n' || c==0) {
@ -365,12 +365,13 @@ void draw_string(int layer, int what, char *s, int rot, int flip, int hcenter, i
}
ss++;
}
my_free(1157, &sss);
}
#else /* !HAS_CAIRO */
/* no CAIRO version */
void draw_string(int layer, int what, char *str, int rot, int flip, int hcenter, int vcenter,
void draw_string(int layer, int what, const char *str, int rot, int flip, int hcenter, int vcenter,
double x1,double y1, double xscale, double yscale)
{
double a=0.0,yy;
@ -431,7 +432,7 @@ void draw_string(int layer, int what, char *str, int rot, int flip, int hcenter,
#endif /* HAS_CAIRO */
void draw_temp_string(GC gctext, int what, char *str, int rot, int flip, int hcenter, int vcenter,
void draw_temp_string(GC gctext, int what, const char *str, int rot, int flip, int hcenter, int vcenter,
double x1,double y1, double xscale, double yscale)
{
if(!has_x) return;
@ -545,11 +546,12 @@ void draw_symbol(int what,int c, int n,int layer,int tmp_flip, int rot,
}
if( (layer==TEXTWIRELAYER && !(inst_ptr[n].flags&2) ) ||
(sym_txt && (layer==TEXTLAYER) && (inst_ptr[n].flags&2) ) ) {
const char *txtptr;
for(j=0;j< symptr->texts;j++)
{
text = symptr->txtptr[j];
if(text.xscale*FONTWIDTH*mooz<1) continue;
text.txt_ptr= translate(n, text.txt_ptr);
txtptr= translate(n, text.txt_ptr);
ROTATION(0.0,0.0,text.x0,text.y0,x1,y1);
textlayer = c;
@ -567,7 +569,8 @@ void draw_symbol(int what,int c, int n,int layer,int tmp_flip, int rot,
cairo_select_font_face (save_ctx, textfont, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
}
#endif
draw_string(textlayer, what, text.txt_ptr,
dbg(1, "drawing string: str=%s prop=%s\n", txtptr, text.prop_ptr);
draw_string(textlayer, what, txtptr,
(text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3,
flip^text.flip, text.hcenter, text.vcenter,
x0+x1, y0+y1, text.xscale, text.yscale);
@ -686,17 +689,17 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,int tmp_flip, int rot,
if(layer==PROPERTYLAYER && sym_txt)
{
const char *txtptr;
for(j=0;j< symptr->texts;j++)
{
text = symptr->txtptr[j];
if(text.xscale*FONTWIDTH*mooz<1) continue;
text.txt_ptr=
translate(n, text.txt_ptr);
txtptr= translate(n, text.txt_ptr);
ROTATION(0.0,0.0,text.x0,text.y0,x1,y1);
#ifdef HAS_CAIRO
customfont = set_text_custom_font(&text);
#endif
if(text.txt_ptr[0]) draw_temp_string(gc, what, text.txt_ptr,
if(txtptr[0]) draw_temp_string(gc, what, txtptr,
(text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3,
flip^text.flip, text.hcenter, text.vcenter, x0+x1, y0+y1, text.xscale, text.yscale);
#ifdef HAS_CAIRO

View File

@ -164,7 +164,7 @@ static void ps_drawline(int gc, double linex1,double liney1,double linex2,double
}
}
static void ps_draw_string(int gctext, char *str,
static void ps_draw_string(int gctext, const char *str,
int rot, int flip, int hcenter, int vcenter,
double x1,double y1,
double xscale, double yscale)
@ -340,12 +340,12 @@ static void ps_draw_symbol(int n,int layer,int tmp_flip, int rot,
if( (layer==TEXTWIRELAYER && !(inst_ptr[n].flags&2) ) ||
(sym_txt && (layer==TEXTLAYER) && (inst_ptr[n].flags&2) ) )
{
const char *txtptr;
for(j=0;j< (inst_ptr[n].ptr+instdef)->texts;j++)
{
text = (inst_ptr[n].ptr+instdef)->txtptr[j];
/* if(text.xscale*FONTWIDTH* mooz<1) continue; */
text.txt_ptr=
translate(n, text.txt_ptr);
txtptr= translate(n, text.txt_ptr);
ROTATION(0.0,0.0,text.x0,text.y0,x1,y1);
textlayer = layer;
if( !(layer == PINLAYER && (inst_ptr[n].flags & 4))) {
@ -353,7 +353,7 @@ static void ps_draw_symbol(int n,int layer,int tmp_flip, int rot,
if(textlayer < 0 || textlayer >= cadlayers) textlayer = layer;
}
if((layer == PINLAYER && inst_ptr[n].flags & 4) || enable_layer[textlayer]) {
ps_draw_string(textlayer, text.txt_ptr,
ps_draw_string(textlayer, txtptr,
(text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3,
flip^text.flip, text.hcenter, text.vcenter,
x0+x1, y0+y1, text.xscale, text.yscale);

View File

@ -1479,7 +1479,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
fscanf(lcc[level].fd, "%lf %lf %d %d %lf %lf ",&tt[i].x0, &tt[i].y0, &tt[i].rot,
&tt[i].flip, &tt[i].xscale, &tt[i].yscale);
if (level>0) {
char* tmp = translate2(lcc, level, tt[i].txt_ptr);
const char* tmp = translate2(lcc, level, tt[i].txt_ptr);
if (tmp) my_strdup(651, &tt[i].txt_ptr, tmp);
ROTATION(0.0, 0.0, tt[i].x0, tt[i].y0, rx1, ry1);
tt[i].x0 = lcc[level].x0 + rx1; tt[i].y0 = lcc[level].y0 + ry1;
@ -1488,7 +1488,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
}
tt[i].prop_ptr=NULL;
load_ascii_string(&tt[i].prop_ptr, lcc[level].fd);
dbg(2, "l_d_s(): loaded text\n");
dbg(1, "l_d_s(): loaded text : t=%s p=%s\n", tt[i].txt_ptr, tt[i].prop_ptr);
my_strdup(351, &tt[i].font, get_tok_value(tt[i].prop_ptr, "font", 0));/*20171206 */

View File

@ -32,7 +32,7 @@ void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2)
{
int j;
Text text;
char *tmp_txt;
const char *tmp_txt;
int rot,flip;
double x0, y0 ;
double text_x0, text_y0;

View File

@ -192,7 +192,7 @@ static void svg_drawline(int gc, double linex1,double liney1,double linex2,doubl
}
}
static void svg_draw_string(int gctext, char *str,
static void svg_draw_string(int gctext, const char *str,
int rot, int flip, int hcenter, int vcenter,
double x1,double y1,
double xscale, double yscale)
@ -367,12 +367,12 @@ static void svg_draw_symbol(int n,int layer,int tmp_flip, int rot,
if( (layer==TEXTWIRELAYER && !(inst_ptr[n].flags&2) ) ||
(sym_txt && (layer==TEXTLAYER) && (inst_ptr[n].flags&2) ) )
{
const char *txtptr;
for(j=0;j< (inst_ptr[n].ptr+instdef)->texts;j++)
{
text = (inst_ptr[n].ptr+instdef)->txtptr[j];
/* if(text.xscale*FONTWIDTH* mooz<1) continue; */
text.txt_ptr=
translate(n, text.txt_ptr);
txtptr= translate(n, text.txt_ptr);
ROTATION(0.0,0.0,text.x0,text.y0,x1,y1);
textlayer = layer;
if( !(layer == PINLAYER && (inst_ptr[n].flags & 4))) {
@ -380,7 +380,7 @@ static void svg_draw_symbol(int n,int layer,int tmp_flip, int rot,
if(textlayer < 0 || textlayer >= cadlayers) textlayer = layer;
}
if((layer == PINLAYER && inst_ptr[n].flags & 4) || enable_layer[textlayer]) {
svg_draw_string(textlayer, text.txt_ptr,
svg_draw_string(textlayer, txtptr,
(text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3,
flip^text.flip, text.hcenter, text.vcenter,
x0+x1, y0+y1, text.xscale, text.yscale);

View File

@ -757,7 +757,7 @@ void new_prop_string(int i, const char *old_prop, int fast, int disable_unique_n
my_free(988, &new_name);
}
char *subst_token(const char *s, const char *tok, const char *new_val)
const char *subst_token(const char *s, const char *tok, const char *new_val)
/* given a string <s> with multiple "token=value ..." assignments */
/* substitute <tok>'s value with <new_val> */
/* if tok not found in s and new_val!=NULL add tok=new_val at end.*/
@ -2454,8 +2454,9 @@ const char *find_nth(const char *str, char sep, int n)
/* substitute given tokens in a string with their corresponding values */
/* ex.: name=@name w=@w l=@l ---> name=m112 w=3e-6 l=0.8e-6 */
/* if s==NULL return emty string */
char *translate(int inst, char* s)
const char *translate(int inst, char* s)
{
static char empty[]="";
static char *result=NULL;
int size=0, tmp;
register int c, state=XBEGIN, space;
@ -2474,7 +2475,7 @@ char *translate(int inst, char* s)
if(!s) {
my_free(1063, &result);
return "";
return empty;
}
size=CADCHUNKALLOC;
@ -2748,8 +2749,9 @@ char *translate(int inst, char* s)
return result;
}
char* translate2(struct Lcc *lcc, int level, char* s)
const char *translate2(struct Lcc *lcc, int level, char* s)
{
static char empty[]="";
static char *result = NULL;
int i, size = 0, tmp, save_tok_size, save_value_size;
register int c, state = XBEGIN, space;
@ -2764,7 +2766,7 @@ char* translate2(struct Lcc *lcc, int level, char* s)
if(!s) {
my_free(1068, &result);
return "";
return empty;
}
size = CADCHUNKALLOC;
my_realloc(661, &result, size);

View File

@ -717,7 +717,7 @@ extern void polygon_bbox(double *x, double *y, int points, double *bx1, double *
extern void arc_bbox(double x, double y, double r, double a, double b, double *bx1, double *by1, double *bx2, double *by2);
extern void bbox(int what,double x1,double y1, double x2, double y2);
extern int set_text_custom_font(Text *txt);
extern int text_bbox(char * str,double xscale, double yscale,
extern int text_bbox(const char * str,double xscale, double yscale,
int rot, int flip, int hcenter, int vcenter, double x1,double y1, double *rx1, double *ry1,
double *rx2, double *ry2);
@ -733,7 +733,7 @@ extern struct int_hashentry *int_hash_lookup(struct int_hashentry **table, int t
extern void free_int_hash(struct int_hashentry **table); /* 20180104 */
#ifdef HAS_CAIRO
extern int text_bbox_nocairo(char * str,double xscale, double yscale,
extern int text_bbox_nocairo(const char * str,double xscale, double yscale,
int rot, int flip, int hcenter, int vcenter, double x1,double y1, double *rx1, double *ry1,
double *rx2, double *ry2);
#endif
@ -759,7 +759,7 @@ extern Selected find_closest_obj(double mx,double my);
extern void find_closest_net_or_symbol_pin(double mx,double my, double *x, double *y);
extern void drawline(int c, int what, double x1,double y1,double x2,double y2);
extern void draw_string(int layer,int what, char *str, int rot, int flip, int hcenter, int vcenter,
extern void draw_string(int layer,int what, const char *str, int rot, int flip, int hcenter, int vcenter,
double x1, double y1, double xscale, double yscale);
extern void draw_symbol(int what,int c, int n,int layer,
int tmp_flip, int tmp_rot, double xoffset, double yoffset);
@ -780,7 +780,7 @@ extern void drawtemppolygon(GC gc, int what, double *x, double *y, int points);
extern void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fill);
extern void draw_temp_symbol(int what, GC gc, int n,int layer,
int tmp_flip, int tmp_rot, double xoffset, double yoffset);
extern void draw_temp_string(GC gc,int what, char *str, int rot, int flip, int hcenter, int vcenter,
extern void draw_temp_string(GC gc,int what, const char *str, int rot, int flip, int hcenter, int vcenter,
double x1, double y1, double xscale, double yscale);
@ -891,8 +891,8 @@ extern struct hashentry *hash_lookup(struct hashentry **table, const char *token
extern const char *find_nth(const char *str, char sep, int n);
extern int isonlydigit(const char *s);
extern char *translate(int inst, char* s);
extern char* translate2(struct Lcc *lcc, int level, char* s);
extern const char *translate(int inst, char* s);
extern const char* translate2(struct Lcc *lcc, int level, char* s);
extern void print_tedax_element(FILE *fd, int inst);
extern void print_spice_element(FILE *fd, int inst);
extern void print_spice_subckt(FILE *fd, int symbol);
@ -915,7 +915,7 @@ extern void my_realloc(int id, void *ptr,size_t size);
extern void *my_calloc(int id, size_t nmemb, size_t size);
extern void my_free(int id, void *ptr);
extern size_t my_strcat(int id, char **, const char *);
extern char *subst_token(const char *s, const char *tok, const char *new_val);
extern const char *subst_token(const char *s, const char *tok, const char *new_val);
extern void new_prop_string(int i, const char *old_prop,int fast, int disable_unique_names);
extern void hash_name(char *token, int remove);
extern void hash_all_names(int n);