Commit 13eb9c357d6472b30b24e51efa93ee5c53d45d51

Ran Benita 2012-07-23T17:41:55

scanner: don't strdup key names The key name is always XkbKeyNameLength (= 4) bytes, so we can maintain it directly in YYSTYPE union and copy when needed, instead of treating it like a full blown string and then copy. This means the scanner checks the length itself. rulescomp under valgrind, before: ==1038== total heap usage: 168,403 allocs, 168,403 frees, 9,732,648 bytes allocated after: ==9377== total heap usage: 155,643 allocs, 155,643 frees, 9,672,788 bytes allocated Signed-off-by: Ran Benita <ran234@gmail.com>

diff --git a/src/xkbcomp/parser.y b/src/xkbcomp/parser.y
index 4f810ac..2c050ab 100644
--- a/src/xkbcomp/parser.y
+++ b/src/xkbcomp/parser.y
@@ -123,6 +123,7 @@ yyerror(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
 	int64_t		 num;
         enum xkb_file_type file_type;
 	char		*str;
+        char            keyName[XkbKeyNameLength];
 	xkb_atom_t	sval;
         enum merge_mode merge;
 	ParseCommon	*any;
@@ -136,18 +137,19 @@ yyerror(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
 	GroupCompatDef	*groupCompat;
 	IndicatorMapDef	*ledMap;
 	IndicatorNameDef *ledName;
-	KeycodeDef	*keyName;
+	KeycodeDef	*keyCode;
 	KeyAliasDef	*keyAlias;
         void            *geom;
 	XkbFile		*file;
 }
 %type <num>     INTEGER FLOAT
-%type <str>     IDENT KEYNAME STRING
+%type <str>     IDENT STRING
+%type <keyName> KEYNAME KeyName
 %type <ival>	Number Integer Float SignedNumber
 %type <merge>	MergeMode OptMergeMode
 %type <file_type> XkbCompositeType FileType
 %type <uval>	DoodadType Flag Flags OptFlags KeyCode
-%type <str>	KeyName MapName OptMapName KeySym
+%type <str>	MapName OptMapName KeySym
 %type <sval>	FieldSpec Ident Element String
 %type <any>	DeclList Decl
 %type <expr>	OptExprList ExprList Expr Term Lhs Terminal ArrayInit KeySyms
@@ -161,7 +163,7 @@ yyerror(struct YYLTYPE *loc, struct parser_param *param, const char *msg)
 %type <groupCompat> GroupCompatDecl
 %type <ledMap>	IndicatorMapDecl
 %type <ledName>	IndicatorNameDecl
-%type <keyName>	KeyNameDecl
+%type <keyCode>	KeyNameDecl
 %type <keyAlias> KeyAliasDecl
 %type <geom>	ShapeDecl SectionDecl SectionBody SectionBodyItem RowBody RowBodyItem
 %type <geom>    Keys Key OverlayDecl OverlayKeyList OverlayKey OutlineList OutlineInList
@@ -352,21 +354,13 @@ VarDecl		:	Lhs EQUALS Expr SEMI
 
 KeyNameDecl	:	KeyName EQUALS KeyCode SEMI
                         {
-			    KeycodeDef *def;
-
-			    def= KeycodeCreate($1,$3);
-			    free($1);
-			    $$= def;
-			}
+                            $$ = KeycodeCreate($1, $3);
+                        }
 		;
 
 KeyAliasDecl	:	ALIAS KeyName EQUALS KeyName SEMI
 			{
-			    KeyAliasDef	*def;
-			    def= KeyAliasCreate($2,$4);
-			    free($2);
-			    free($4);
-			    $$= def;
+			    $$= KeyAliasCreate($2,$4);
 			}
 		;
 
@@ -416,7 +410,7 @@ KeyTypeDecl	:	TYPE String OBRACE
 SymbolsDecl	:	KEY KeyName OBRACE
 			    SymbolsBody
 			CBRACE SEMI
-			{ $$= SymbolsCreate($2,(ExprDef *)$4); free($2); }
+			{ $$= SymbolsCreate($2,(ExprDef *)$4); }
 		;
 
 SymbolsBody	:	SymbolsBody COMMA SymbolsVarDecl
@@ -509,7 +503,7 @@ Keys		:	Keys COMMA Key
 		;
 
 Key		:	KeyName
-			{ free($1); $$= NULL; }
+			{ $$= NULL; }
 		|	OBRACE ExprList CBRACE
 			{ FreeStmt(&$2->common); $$= NULL; }
 		;
@@ -525,7 +519,7 @@ OverlayKeyList	:	OverlayKeyList COMMA OverlayKey
 		;
 
 OverlayKey	:	KeyName EQUALS KeyName
-			{ free($1); free($3); $$= NULL; }
+			{ $$= NULL; }
 		;
 
 OutlineList	:	OutlineList COMMA OutlineInList
@@ -717,9 +711,7 @@ Terminal	:	String
 			{
 			    ExprDef *expr;
 			    expr= ExprCreate(ExprValue,TypeKeyName);
-			    memset(expr->value.keyName,0,5);
 			    strncpy(expr->value.keyName,$1,4);
-			    free($1);
 			    $$= expr;
 			}
 		;
@@ -775,7 +767,7 @@ Integer		:	INTEGER		{ $$= $1; }
 KeyCode         :       INTEGER         { $$= $1; }
                 ;
 
-KeyName		:	KEYNAME		{ $$= $1; }
+KeyName		:	KEYNAME		{ strncpy($$, $1, XkbKeyNameLength); }
 		;
 
 Ident		:	IDENT
diff --git a/src/xkbcomp/parseutils.c b/src/xkbcomp/parseutils.c
index 6ec3b08..d4f7608 100644
--- a/src/xkbcomp/parseutils.c
+++ b/src/xkbcomp/parseutils.c
@@ -106,7 +106,7 @@ ExprCreateBinary(unsigned op, ExprDef * left, ExprDef * right)
 }
 
 KeycodeDef *
-KeycodeCreate(const char *name, unsigned long value)
+KeycodeCreate(char keyName[XkbKeyNameLength], unsigned long value)
 {
     KeycodeDef *def;
 
@@ -114,14 +114,14 @@ KeycodeCreate(const char *name, unsigned long value)
 
     def->common.stmtType = StmtKeycodeDef;
     def->common.next = NULL;
-    strncpy(def->name, name, XkbKeyNameLength);
+    strncpy(def->name, keyName, XkbKeyNameLength);
     def->name[XkbKeyNameLength] = '\0';
     def->value = value;
     return def;
 }
 
 KeyAliasDef *
-KeyAliasCreate(const char *alias, const char *real)
+KeyAliasCreate(char alias[XkbKeyNameLength], char real[XkbKeyNameLength])
 {
     KeyAliasDef *def;
 
@@ -205,7 +205,7 @@ KeyTypeCreate(xkb_atom_t name, VarDef * body)
 }
 
 SymbolsDef *
-SymbolsCreate(const char *keyName, ExprDef *symbols)
+SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols)
 {
     SymbolsDef *def;
 
@@ -214,8 +214,7 @@ SymbolsCreate(const char *keyName, ExprDef *symbols)
     def->common.stmtType = StmtSymbolsDef;
     def->common.next = NULL;
     def->merge = MERGE_DEFAULT;
-    memset(def->keyName, 0, 5);
-    strncpy(def->keyName, keyName, 4);
+    strncpy(def->keyName, keyName, XkbKeyNameLength);
     def->symbols = symbols;
     return def;
 }
diff --git a/src/xkbcomp/parseutils.h b/src/xkbcomp/parseutils.h
index 252d8d8..52d8c3c 100644
--- a/src/xkbcomp/parseutils.h
+++ b/src/xkbcomp/parseutils.h
@@ -58,11 +58,11 @@ ExprCreateUnary(unsigned op, unsigned type, ExprDef *child);
 extern ExprDef *
 ExprCreateBinary(unsigned op, ExprDef *left, ExprDef *right);
 
-extern KeycodeDef *
-KeycodeCreate(const char *name, unsigned long value);
+KeycodeDef *
+KeycodeCreate(char keyName[XkbKeyNameLength], unsigned long value);
 
 extern KeyAliasDef *
-KeyAliasCreate(const char *alias, const char *real);
+KeyAliasCreate(char keyName[XkbKeyNameLength], char real[XkbKeyNameLength]);
 
 extern VModDef *
 VModCreate(xkb_atom_t name, ExprDef *value);
@@ -80,7 +80,7 @@ extern KeyTypeDef *
 KeyTypeCreate(xkb_atom_t name, VarDef *body);
 
 extern SymbolsDef *
-SymbolsCreate(const char *keyName, ExprDef *symbols);
+SymbolsCreate(char keyName[XkbKeyNameLength], ExprDef *symbols);
 
 extern GroupCompatDef *
 GroupCompatCreate(int group, ExprDef *def);
diff --git a/src/xkbcomp/scanner.l b/src/xkbcomp/scanner.l
index 6484a1c..e8f159a 100644
--- a/src/xkbcomp/scanner.l
+++ b/src/xkbcomp/scanner.l
@@ -76,11 +76,18 @@ scanner_error_extra(struct YYLTYPE *loc, struct scanner_extra *extra,
 			return STRING;
 		    }
 <S_KEY>\> {
-			BEGIN(INITIAL);
-			*yyextra->s = '\0';
-			yylval->str = strdup(yyextra->scanBuf);
-			return KEYNAME;
-		    }
+                        BEGIN(INITIAL);
+
+                        *yyextra->s = '\0';
+                        if (yyextra->s - yyextra->scanBuf > XkbKeyNameLength) {
+                            scanner_error_extra(yylloc, yyextra,
+                                                "Key name too long");
+                            return ERROR_TOK;
+                        }
+
+                        strncpy(yylval->keyName, yyextra->scanBuf, XkbKeyNameLength);
+                        return KEYNAME;
+                    }
 
 <S_STR,S_KEY>\\[0-7]{1,3} {
 			/* octal escape sequence */