Mercurial > vim
comparison src/vim9compile.c @ 30815:90a257beac7a v9.0.0742
patch 9.0.0742: reading past end of the line when compiling a function
Commit: https://github.com/vim/vim/commit/3558afe9e9e904cabb8475392d859f2d2fc21041
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Oct 13 16:12:57 2022 +0100
patch 9.0.0742: reading past end of the line when compiling a function
Problem: Reading past end of the line when compiling a function with
errors.
Solution: Do not return an invalid pointer. Fix skipping redirection.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 13 Oct 2022 17:15:05 +0200 |
parents | 9d2c4d49b006 |
children | 3e8aed429cc5 |
comparison
equal
deleted
inserted
replaced
30814:b3d8ec41adf1 | 30815:90a257beac7a |
---|---|
1282 } | 1282 } |
1283 semsg(_(e_cannot_declare_a_scope_variable), scope, name); | 1283 semsg(_(e_cannot_declare_a_scope_variable), scope, name); |
1284 } | 1284 } |
1285 | 1285 |
1286 /* | 1286 /* |
1287 * Return TRUE if "name" is a valid register to use. | |
1288 * Return FALSE and give an error message if not. | |
1289 */ | |
1290 static int | |
1291 valid_dest_reg(int name) | |
1292 { | |
1293 if ((name == '@' || valid_yank_reg(name, FALSE)) && name != '.') | |
1294 return TRUE; | |
1295 emsg_invreg(name); | |
1296 return FAIL; | |
1297 } | |
1298 | |
1299 /* | |
1287 * For one assignment figure out the type of destination. Return it in "dest". | 1300 * For one assignment figure out the type of destination. Return it in "dest". |
1288 * When not recognized "dest" is not set. | 1301 * When not recognized "dest" is not set. |
1289 * For an option "option_scope" is set. | 1302 * For an option "option_scope" is set. |
1290 * For a v:var "vimvaridx" is set. | 1303 * For a v:var "vimvaridx" is set. |
1291 * "type" is set to the destination type if known, unchanted otherwise. | 1304 * "type" is set to the destination type if known, unchanted otherwise. |
1362 *dest = dest_env; | 1375 *dest = dest_env; |
1363 *type = &t_string; | 1376 *type = &t_string; |
1364 } | 1377 } |
1365 else if (*name == '@') | 1378 else if (*name == '@') |
1366 { | 1379 { |
1367 if (name[1] != '@' | 1380 if (!valid_dest_reg(name[1])) |
1368 && (!valid_yank_reg(name[1], FALSE) || name[1] == '.')) | |
1369 { | |
1370 emsg_invreg(name[1]); | |
1371 return FAIL; | 1381 return FAIL; |
1372 } | |
1373 *dest = dest_reg; | 1382 *dest = dest_reg; |
1374 *type = name[1] == '#' ? &t_number_or_string : &t_string; | 1383 *type = name[1] == '#' ? &t_number_or_string : &t_string; |
1375 } | 1384 } |
1376 else if (STRNCMP(name, "g:", 2) == 0) | 1385 else if (STRNCMP(name, "g:", 2) == 0) |
1377 { | 1386 { |
1443 // "dest_end" is the end of the destination, including "[expr]" or | 1452 // "dest_end" is the end of the destination, including "[expr]" or |
1444 // ".name". | 1453 // ".name". |
1445 // "var_end" is the end of the variable/option/etc. name. | 1454 // "var_end" is the end of the variable/option/etc. name. |
1446 lhs->lhs_dest_end = skip_var_one(var_start, FALSE); | 1455 lhs->lhs_dest_end = skip_var_one(var_start, FALSE); |
1447 if (*var_start == '@') | 1456 if (*var_start == '@') |
1457 { | |
1458 if (!valid_dest_reg(var_start[1])) | |
1459 return FAIL; | |
1448 var_end = var_start + 2; | 1460 var_end = var_start + 2; |
1461 } | |
1449 else | 1462 else |
1450 { | 1463 { |
1451 // skip over the leading "&", "&l:", "&g:" and "$" | 1464 // skip over the leading "&", "&l:", "&g:" and "$" |
1452 var_end = skip_option_env_lead(var_start); | 1465 var_end = skip_option_env_lead(var_start); |
1453 var_end = to_name_end(var_end, TRUE); | 1466 var_end = to_name_end(var_end, TRUE); |