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);