From 0c8539c8672a2e22605a364b74bc4d3fcf9803b1 Mon Sep 17 00:00:00 2001 From: Alexey Gladkov Date: Sun, 23 Jan 2011 04:34:33 +0300 Subject: [PATCH] loadkeys: Fix some memory leaks Signed-off-by: Alexey Gladkov --- src/analyze.c | 136 +++++++++++++++++++++++++++------------------------------ src/analyze.l | 1 + src/findfile.c | 28 +++++++++--- src/loadkeys.c | 13 ++++-- src/loadkeys.y | 13 ++++-- src/xmalloc.c | 7 +++ src/xmalloc.h | 1 + 7 files changed, 116 insertions(+), 83 deletions(-) diff --git a/src/analyze.c b/src/analyze.c index 3d7e258..90b037c 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -142,15 +142,7 @@ typedef unsigned int flex_uint32_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else #define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -357,7 +349,11 @@ extern char *yytext; static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); +#ifdef __GNUC__ +static void yy_fatal_error (yyconst char msg[] ) __attribute__((noreturn)); +#else static void yy_fatal_error (yyconst char msg[] ); +#endif /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. @@ -823,7 +819,7 @@ extern void open_include(char *s); -#line 827 "analyze.c" +#line 823 "analyze.c" #define INITIAL 0 #define RVALUE 1 @@ -905,12 +901,7 @@ static int input (void ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else #define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -1026,7 +1017,7 @@ YY_DECL * yylval to YYLVAL_UNDEF. Then it might be overwritten by specific rules. */ yylval = YYLVAL_UNDEF; -#line 1030 "analyze.c" +#line 1021 "analyze.c" if ( !(yy_init) ) { @@ -1123,13 +1114,14 @@ YY_RULE_SETUP strcpy(s, yytext+1); s[l-2] = 0; /* wipe out " */ open_include(s); + free(s); BEGIN(0); } YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP -#line 88 "analyze.l" +#line 89 "analyze.l" { yyerror("expected filename between quotes"); BEGIN(0); } @@ -1137,18 +1129,18 @@ YY_RULE_SETUP case 4: /* rule 4 can match eol */ YY_RULE_SETUP -#line 91 "analyze.l" +#line 92 "analyze.l" {line_nr++;} YY_BREAK case 5: /* rule 5 can match eol */ YY_RULE_SETUP -#line 92 "analyze.l" +#line 93 "analyze.l" {line_nr++;BEGIN(0);return(EOL);} YY_BREAK case 6: YY_RULE_SETUP -#line 93 "analyze.l" +#line 94 "analyze.l" ; /* do nothing */ YY_BREAK case 7: @@ -1157,224 +1149,226 @@ case 7: (yy_c_buf_p) = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP -#line 94 "analyze.l" +#line 95 "analyze.l" ; /* do nothing */ YY_BREAK case 8: YY_RULE_SETUP -#line 95 "analyze.l" +#line 96 "analyze.l" {BEGIN(RVALUE);rvalct=0;return(EQUALS);} YY_BREAK case 9: YY_RULE_SETUP -#line 96 "analyze.l" +#line 97 "analyze.l" {return(DASH);} YY_BREAK case 10: YY_RULE_SETUP -#line 97 "analyze.l" +#line 98 "analyze.l" {return(COMMA);} YY_BREAK case 11: YY_RULE_SETUP -#line 98 "analyze.l" +#line 99 "analyze.l" {return(PLUS);} YY_BREAK case 12: YY_RULE_SETUP -#line 99 "analyze.l" +#line 100 "analyze.l" {yylval=strtol(yytext+1,NULL,16);if(yylval>=0xf000)lkfatal1("unicode keysym out of range: %s",yytext);return(UNUMBER);} YY_BREAK case 13: YY_RULE_SETUP -#line 100 "analyze.l" +#line 101 "analyze.l" {yylval=strtol(yytext,NULL,0);return(NUMBER);} YY_BREAK case 14: YY_RULE_SETUP -#line 101 "analyze.l" +#line 102 "analyze.l" {return((yylval=ksymtocode(yytext, TO_AUTO))==-1?ERROR:LITERAL);} YY_BREAK case 15: YY_RULE_SETUP -#line 102 "analyze.l" +#line 103 "analyze.l" {return(CHARSET);} YY_BREAK case 16: YY_RULE_SETUP -#line 103 "analyze.l" +#line 104 "analyze.l" {return(KEYMAPS);} YY_BREAK case 17: YY_RULE_SETUP -#line 104 "analyze.l" +#line 105 "analyze.l" {return(KEYCODE);} YY_BREAK case 18: YY_RULE_SETUP -#line 105 "analyze.l" +#line 106 "analyze.l" {BEGIN(RVALUE);return(STRING);} YY_BREAK case 19: YY_RULE_SETUP -#line 106 "analyze.l" +#line 107 "analyze.l" {return(PLAIN);} YY_BREAK case 20: YY_RULE_SETUP -#line 107 "analyze.l" +#line 108 "analyze.l" {return(SHIFT);} YY_BREAK case 21: YY_RULE_SETUP -#line 108 "analyze.l" +#line 109 "analyze.l" {return(CONTROL);} YY_BREAK case 22: YY_RULE_SETUP -#line 109 "analyze.l" +#line 110 "analyze.l" {return(ALT);} YY_BREAK case 23: YY_RULE_SETUP -#line 110 "analyze.l" +#line 111 "analyze.l" {return(ALTGR);} YY_BREAK case 24: YY_RULE_SETUP -#line 111 "analyze.l" +#line 112 "analyze.l" {return(SHIFTL);} YY_BREAK case 25: YY_RULE_SETUP -#line 112 "analyze.l" +#line 113 "analyze.l" {return(SHIFTR);} YY_BREAK case 26: YY_RULE_SETUP -#line 113 "analyze.l" +#line 114 "analyze.l" {return(CTRLL);} YY_BREAK case 27: YY_RULE_SETUP -#line 114 "analyze.l" +#line 115 "analyze.l" {return(CTRLR);} YY_BREAK case 28: YY_RULE_SETUP -#line 115 "analyze.l" +#line 116 "analyze.l" {return(CAPSSHIFT);} YY_BREAK case 29: YY_RULE_SETUP -#line 116 "analyze.l" +#line 117 "analyze.l" {return(ALT_IS_META);} YY_BREAK case 30: YY_RULE_SETUP -#line 117 "analyze.l" +#line 118 "analyze.l" {return(STRINGS);} YY_BREAK case 31: YY_RULE_SETUP -#line 118 "analyze.l" +#line 119 "analyze.l" {return(COMPOSE);} YY_BREAK case 32: YY_RULE_SETUP -#line 119 "analyze.l" +#line 120 "analyze.l" {return(AS);} YY_BREAK case 33: YY_RULE_SETUP -#line 120 "analyze.l" +#line 121 "analyze.l" {return(USUAL);} YY_BREAK case 34: YY_RULE_SETUP -#line 121 "analyze.l" +#line 122 "analyze.l" {BEGIN(RVALUE); return(TO);} YY_BREAK case 35: YY_RULE_SETUP -#line 122 "analyze.l" +#line 123 "analyze.l" {return(ON);} YY_BREAK case 36: YY_RULE_SETUP -#line 123 "analyze.l" +#line 124 "analyze.l" {return(FOR);} YY_BREAK case 37: YY_RULE_SETUP -#line 124 "analyze.l" +#line 125 "analyze.l" {yylval = strtol(yytext+2,NULL,8); return(CCHAR);} YY_BREAK case 38: YY_RULE_SETUP -#line 125 "analyze.l" +#line 126 "analyze.l" {yylval = (unsigned char) yytext[2]; return(CCHAR);} YY_BREAK case 39: YY_RULE_SETUP -#line 126 "analyze.l" +#line 127 "analyze.l" {yylval = (unsigned char) yytext[1]; return(CCHAR);} YY_BREAK case 40: YY_RULE_SETUP -#line 127 "analyze.l" +#line 128 "analyze.l" {p=(char *) kbs_buf.kb_string; pmax=p+sizeof(kbs_buf.kb_string)-1; BEGIN(STR);} YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(RVALUE): +case YY_STATE_EOF(STR): +case YY_STATE_EOF(INCLSTR): +#line 131 "analyze.l" +{yyterminate();} + YY_BREAK case 41: YY_RULE_SETUP -#line 130 "analyze.l" +#line 132 "analyze.l" {if(p>=pmax)stringovfl();*p++=strtol(yytext+1,NULL,8);} YY_BREAK case 42: YY_RULE_SETUP -#line 131 "analyze.l" +#line 133 "analyze.l" {if(p>=pmax)stringovfl();*p++='"';} YY_BREAK case 43: YY_RULE_SETUP -#line 132 "analyze.l" +#line 134 "analyze.l" {if(p>=pmax)stringovfl();*p++='\\';} YY_BREAK case 44: YY_RULE_SETUP -#line 133 "analyze.l" +#line 135 "analyze.l" {if(p>=pmax)stringovfl();*p++='\n';} YY_BREAK case 45: /* rule 45 can match eol */ YY_RULE_SETUP -#line 134 "analyze.l" +#line 136 "analyze.l" {char *ptmp=p;p+=strlen(yytext); if(p>pmax)stringovfl();strcpy(ptmp,yytext);} YY_BREAK case 46: YY_RULE_SETUP -#line 136 "analyze.l" +#line 138 "analyze.l" {*p='\0';BEGIN(0);return(STRLITERAL);} YY_BREAK case 47: YY_RULE_SETUP -#line 137 "analyze.l" +#line 139 "analyze.l" {return(ERROR); /* report any unknown characters */} YY_BREAK case 48: YY_RULE_SETUP -#line 138 "analyze.l" +#line 140 "analyze.l" ECHO; YY_BREAK -#line 1373 "analyze.c" -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(RVALUE): -case YY_STATE_EOF(STR): -case YY_STATE_EOF(INCLSTR): - yyterminate(); +#line 1372 "analyze.c" case YY_END_OF_BUFFER: { @@ -1885,9 +1879,9 @@ static void yy_load_buffer_state (void) yyfree((void *) b ); } -#ifndef __cplusplus +#if defined(YY_NO_UNISTD_H) && !defined(__cplusplus) extern int isatty (int ); -#endif /* __cplusplus */ +#endif /* YY_NO_UNISTD_H && !__cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, @@ -2132,7 +2126,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) #define YY_EXIT_FAILURE 2 #endif -static void attr_noreturn yy_fatal_error (yyconst char* msg ) +static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); @@ -2333,7 +2327,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 138 "analyze.l" +#line 140 "analyze.l" #include "ksyms.h" diff --git a/src/analyze.l b/src/analyze.l index b231564..cf4970d 100644 --- a/src/analyze.l +++ b/src/analyze.l @@ -83,6 +83,7 @@ To to|To|TO strcpy(s, yytext+1); s[l-2] = 0; /* wipe out " */ open_include(s); + free(s); BEGIN(0); } [^"]|\"\"|\"[^"\n]*{Eol} { diff --git a/src/findfile.c b/src/findfile.c index be11388..c152084 100644 --- a/src/findfile.c +++ b/src/findfile.c @@ -42,6 +42,7 @@ pipe_open(struct decompressor *dc) { fp = popen(pipe_cmd, "r"); if (fp == NULL) fprintf(stderr, _("error executing %s\n"), pipe_cmd); + xfree(pipe_cmd); return fp; } @@ -90,8 +91,10 @@ findfile_in_dir(char *fnam, char *dir, int recdepth, char **suf) { contains the file we are looking for. */ StartScan: d = opendir(dir); - if (d == NULL) + if (d == NULL) { + xfree(fdir); return NULL; + } while ((de = readdir(d)) != NULL) { struct stat statbuf; int okdir; @@ -116,10 +119,14 @@ findfile_in_dir(char *fnam, char *dir, int recdepth, char **suf) { fp = findfile_in_dir(ff+1, a, 0, suf); if (!fp && recdepth) fp = findfile_in_dir(fnam, a, recdepth-1, suf); - if (fp) + if (fp) { + xfree(a); + xfree(fdir); + closedir(d); return fp; + } } - free(a); + xfree(a); } if (secondpass) @@ -145,14 +152,20 @@ findfile_in_dir(char *fnam, char *dir, int recdepth, char **suf) { for(sp = suf; *sp; sp++) { int l; - if (!strcmp(p, *sp)) + if (!strcmp(p, *sp)) { + xfree(fdir); + closedir(d); return maybe_pipe_open(); + } l = strlen(*sp); if (strncmp(p,*sp,l) == 0) { for (dc = &decompressors[0]; dc->cmd; dc++) - if (strcmp(p+l, dc->ext) == 0) + if (strcmp(p+l, dc->ext) == 0) { + xfree(fdir); + closedir(d); return pipe_open(dc); + } } } } @@ -161,6 +174,7 @@ findfile_in_dir(char *fnam, char *dir, int recdepth, char **suf) { secondpass = 1; goto StartScan; } + xfree(fdir); return NULL; } @@ -226,12 +240,14 @@ FILE *findfile(char *fnam, char **dirpath, char **suffixes) { recdepth++; } if (dl == 0) { - dir = "."; + xfree(dir); + dir = xstrdup("."); } else if (dl > 1 && dir[dl-1] == '/') { dir[dl-1] = 0; } fp = findfile_in_dir(fnam, dir, recdepth, suffixes); + xfree(dir); if (fp) return fp; } diff --git a/src/loadkeys.c b/src/loadkeys.c index 6fe57a6..429cbc5 100644 --- a/src/loadkeys.c +++ b/src/loadkeys.c @@ -2250,7 +2250,7 @@ main(int argc, char *argv[]) { } extern char pathname[]; -char *filename; +char *filename = NULL; int line_nr = 1; int @@ -2264,6 +2264,7 @@ yyerror(const char *s) { void attr_noreturn lkfatal(const char *s) { fprintf(stderr, "%s: %s:%d: %s\n", progname, filename, line_nr, s); + xfree(filename); exit(1); } @@ -2272,6 +2273,7 @@ lkfatal0(const char *s, int d) { fprintf(stderr, "%s: %s:%d: ", progname, filename, line_nr); fprintf(stderr, s, d); fprintf(stderr, "\n"); + xfree(filename); exit(1); } @@ -2280,6 +2282,7 @@ lkfatal1(const char *s, const char *s2) { fprintf(stderr, "%s: %s:%d: ", progname, filename, line_nr); fprintf(stderr, s, s2); fprintf(stderr, "\n"); + xfree(filename); exit(1); } @@ -2371,9 +2374,10 @@ FILE *find_incl_file_near_fn(char *s, char *fn) { strcpy(t2, t); strcat(t2, "../../include/"); f = findfile(s, include_dirpath2, include_suffixes); - if (f) - return f; + xfree(t1); + xfree(t2); } + xfree(t); return f; } @@ -2457,6 +2461,7 @@ open_include(char *s) { yyin = find_incl_file(s); if (!yyin) lkfatal1(_("cannot open include file %s"), s); + xfree(filename); filename = xstrdup(pathname); line_nr = 1; yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); @@ -2725,6 +2730,8 @@ defkeys(int fd, int kbd_mode) { j, (key_map[i])[j]); } } + xfree(key_map[i]); + xfree(keymap_was_set[i]); } else if (keymaps_line_seen && !defining[i]) { /* deallocate keymap */ ke.kb_index = 0; diff --git a/src/loadkeys.y b/src/loadkeys.y index be541ca..fa9e101 100644 --- a/src/loadkeys.y +++ b/src/loadkeys.y @@ -447,7 +447,7 @@ main(int argc, char *argv[]) { } extern char pathname[]; -char *filename; +char *filename = NULL; int line_nr = 1; int @@ -461,6 +461,7 @@ yyerror(const char *s) { void attr_noreturn lkfatal(const char *s) { fprintf(stderr, "%s: %s:%d: %s\n", progname, filename, line_nr, s); + xfree(filename); exit(1); } @@ -469,6 +470,7 @@ lkfatal0(const char *s, int d) { fprintf(stderr, "%s: %s:%d: ", progname, filename, line_nr); fprintf(stderr, s, d); fprintf(stderr, "\n"); + xfree(filename); exit(1); } @@ -477,6 +479,7 @@ lkfatal1(const char *s, const char *s2) { fprintf(stderr, "%s: %s:%d: ", progname, filename, line_nr); fprintf(stderr, s, s2); fprintf(stderr, "\n"); + xfree(filename); exit(1); } @@ -568,9 +571,10 @@ FILE *find_incl_file_near_fn(char *s, char *fn) { strcpy(t2, t); strcat(t2, "../../include/"); f = findfile(s, include_dirpath2, include_suffixes); - if (f) - return f; + xfree(t1); + xfree(t2); } + xfree(t); return f; } @@ -654,6 +658,7 @@ open_include(char *s) { yyin = find_incl_file(s); if (!yyin) lkfatal1(_("cannot open include file %s"), s); + xfree(filename); filename = xstrdup(pathname); line_nr = 1; yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); @@ -922,6 +927,8 @@ defkeys(int fd, int kbd_mode) { j, (key_map[i])[j]); } } + xfree(key_map[i]); + xfree(keymap_was_set[i]); } else if (keymaps_line_seen && !defining[i]) { /* deallocate keymap */ ke.kb_index = 0; diff --git a/src/xmalloc.c b/src/xmalloc.c index 081db0a..0928fd7 100644 --- a/src/xmalloc.c +++ b/src/xmalloc.c @@ -39,3 +39,10 @@ xstrdup(char *p) { nomem(); return q; } + +void * +xfree(void *p) { + if (p != NULL) + free(p); + return NULL; +} diff --git a/src/xmalloc.h b/src/xmalloc.h index 0120235..61c8b4f 100644 --- a/src/xmalloc.h +++ b/src/xmalloc.h @@ -5,5 +5,6 @@ extern void *xmalloc(size_t sz); extern void *xrealloc(void *p, size_t sz); extern char *xstrdup(char *p); +extern void *xfree(void *p); #endif /* _XMALLOC_H */ -- 2.7.4