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>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
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 */