|
40 | 40 | #define GUARDEDOFFSET 1000000 // base for "guarded" sign id's |
41 | 41 | #define MAX_COLOR_LENGTH 32 // max length of color name in defineAnnoType |
42 | 42 |
|
| 43 | +// Characters valid in a sign/highlight group name |
| 44 | +#define VALID_CHARS (char_u *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" |
| 45 | +#define VALID_SIGNNAME_CHARS VALID_CHARS "_" |
| 46 | +#define VALID_COLOR_CHARS VALID_CHARS "#" |
| 47 | + |
43 | 48 | // The first implementation (working only with Netbeans) returned "1.1". The |
44 | 49 | // protocol implemented here also supports A-A-P. |
45 | 50 | static char *ExtEdProtocolVersion = "2.5"; |
@@ -77,6 +82,22 @@ static int dosetvisible = FALSE; |
77 | 82 | static int needupdate = 0; |
78 | 83 | static int inAtomic = 0; |
79 | 84 |
|
| 85 | +/* |
| 86 | + * Return TRUE if "str" contains only characters from "allowed". |
| 87 | + * Used to validate NetBeans-supplied strings before interpolating them |
| 88 | + * into Ex commands via coloncmd(). |
| 89 | + */ |
| 90 | + static int |
| 91 | +nb_is_safe_string(char_u *str, char_u *allowed) |
| 92 | +{ |
| 93 | + if (str == NULL) |
| 94 | + return FALSE; |
| 95 | + for (char_u *p = str; *p != NUL; p++) |
| 96 | + if (vim_strchr(allowed, *p) == NULL) |
| 97 | + return FALSE; |
| 98 | + return TRUE; |
| 99 | +} |
| 100 | + |
80 | 101 | /* |
81 | 102 | * Callback invoked when the channel is closed. |
82 | 103 | */ |
@@ -1949,6 +1970,15 @@ nb_do_cmd( |
1949 | 1970 | VIM_CLEAR(typeName); |
1950 | 1971 | parse_error = TRUE; |
1951 | 1972 | } |
| 1973 | + else if (!nb_is_safe_string(typeName, VALID_SIGNNAME_CHARS) || |
| 1974 | + (*fg != NUL && !nb_is_safe_string(fg, VALID_COLOR_CHARS)) || |
| 1975 | + (*bg != NUL && !nb_is_safe_string(bg, VALID_COLOR_CHARS))) |
| 1976 | + { |
| 1977 | + nbdebug((" invalid chars in typeName/fg/bg in defineAnnoType\n")); |
| 1978 | + emsg(_(e_invalid_identifier_in_defineannotype)); |
| 1979 | + VIM_CLEAR(typeName); |
| 1980 | + parse_error = TRUE; |
| 1981 | + } |
1952 | 1982 | else if (typeName != NULL && tooltip != NULL && glyphFile != NULL) |
1953 | 1983 | addsigntype(buf, typeNum, typeName, tooltip, glyphFile, fg, bg); |
1954 | 1984 |
|
@@ -2321,10 +2351,24 @@ special_keys(char_u *args) |
2321 | 2351 |
|
2322 | 2352 | if (strlen(tok) + i < KEYBUFLEN) |
2323 | 2353 | { |
2324 | | - vim_strncpy((char_u *)&keybuf[i], (char_u *)tok, KEYBUFLEN - i - 1); |
2325 | | - vim_snprintf(cmdbuf, sizeof(cmdbuf), |
2326 | | - "<silent><%s> :nbkey %s<CR>", keybuf, keybuf); |
2327 | | - do_map(MAPTYPE_MAP, (char_u *)cmdbuf, MODE_NORMAL, FALSE); |
| 2354 | + // Only allow alphanumeric and function-key name characters. |
| 2355 | + // Reject anything else to prevent map command injection. |
| 2356 | + int safe = TRUE; |
| 2357 | + for (char_u *tp = (char_u *)tok; *tp != NUL; tp++) |
| 2358 | + { |
| 2359 | + if (!ASCII_ISALNUM(*tp) && *tp != '-') |
| 2360 | + { |
| 2361 | + safe = FALSE; |
| 2362 | + break; |
| 2363 | + } |
| 2364 | + } |
| 2365 | + if (safe) |
| 2366 | + { |
| 2367 | + vim_strncpy((char_u *)&keybuf[i], (char_u *)tok, KEYBUFLEN - i - 1); |
| 2368 | + vim_snprintf(cmdbuf, sizeof(cmdbuf), |
| 2369 | + "<silent><%s> :nbkey %s<CR>", keybuf, keybuf); |
| 2370 | + do_map(MAPTYPE_MAP, (char_u *)cmdbuf, MODE_NORMAL, FALSE); |
| 2371 | + } |
2328 | 2372 | } |
2329 | 2373 | tok = strtok(NULL, " "); |
2330 | 2374 | } |
|
0 commit comments