comparison src/textprop.c @ 29552:89a97f70e8eb v9.0.0117

patch 9.0.0117: text of removed textprop with text is not freed Commit: https://github.com/vim/vim/commit/3a4cd39d476474e20e88ebf120ca6070cc0d0072 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jul 30 22:17:18 2022 +0100 patch 9.0.0117: text of removed textprop with text is not freed Problem: Text of removed textprop with text is not freed. Solution: Free the text when the property is removed. Reduce the array size to ignore NULLs at the end.
author Bram Moolenaar <Bram@vim.org>
date Sat, 30 Jul 2022 23:30:05 +0200
parents 057c26b5c33a
children 14b139cbec49
comparison
equal deleted inserted replaced
29551:79f45796181b 29552:89a97f70e8eb
1231 linenr_T first_changed = 0; 1231 linenr_T first_changed = 0;
1232 linenr_T last_changed = 0; 1232 linenr_T last_changed = 0;
1233 dict_T *dict; 1233 dict_T *dict;
1234 buf_T *buf = curbuf; 1234 buf_T *buf = curbuf;
1235 int do_all; 1235 int do_all;
1236 int id = -1; 1236 int id = -MAXCOL;
1237 int type_id = -1; 1237 int type_id = -1;
1238 int both; 1238 int both;
1239 int did_remove_text = FALSE;
1239 1240
1240 rettv->vval.v_number = 0; 1241 rettv->vval.v_number = 0;
1241 1242
1242 if (in_vim9script() 1243 if (in_vim9script()
1243 && (check_for_dict_arg(argvars, 0) == FAIL 1244 && (check_for_dict_arg(argvars, 0) == FAIL
1284 return; 1285 return;
1285 type_id = type->pt_id; 1286 type_id = type->pt_id;
1286 } 1287 }
1287 both = dict_get_bool(dict, "both", FALSE); 1288 both = dict_get_bool(dict, "both", FALSE);
1288 1289
1289 if (id == -1 && type_id == -1) 1290 if (id == -MAXCOL && type_id == -1)
1290 { 1291 {
1291 emsg(_(e_need_at_least_one_of_id_or_type)); 1292 emsg(_(e_need_at_least_one_of_id_or_type));
1292 return; 1293 return;
1293 } 1294 }
1294 if (both && (id == -1 || type_id == -1)) 1295 if (both && (id == -MAXCOL || type_id == -1))
1295 { 1296 {
1296 emsg(_(e_need_id_and_type_with_both)); 1297 emsg(_(e_need_id_and_type_with_both));
1297 return; 1298 return;
1298 } 1299 }
1299 1300
1348 mch_memmove(cur_prop, cur_prop + sizeof(textprop_T), 1349 mch_memmove(cur_prop, cur_prop + sizeof(textprop_T),
1349 taillen); 1350 taillen);
1350 buf->b_ml.ml_line_len -= sizeof(textprop_T); 1351 buf->b_ml.ml_line_len -= sizeof(textprop_T);
1351 --idx; 1352 --idx;
1352 1353
1354 if (textprop.tp_id < 0)
1355 {
1356 garray_T *gap = &buf->b_textprop_text;
1357 int ii = -textprop.tp_id - 1;
1358
1359 // negative ID: property with text - free the text
1360 if (ii < gap->ga_len)
1361 {
1362 char_u **p = ((char_u **)gap->ga_data) + ii;
1363 vim_free(*p);
1364 *p = NULL;
1365 did_remove_text = TRUE;
1366 }
1367 }
1368
1353 if (first_changed == 0) 1369 if (first_changed == 0)
1354 first_changed = lnum; 1370 first_changed = lnum;
1355 last_changed = lnum; 1371 last_changed = lnum;
1356 ++rettv->vval.v_number; 1372 ++rettv->vval.v_number;
1357 if (!do_all) 1373 if (!do_all)
1358 break; 1374 break;
1359 } 1375 }
1360 } 1376 }
1361 } 1377 }
1362 } 1378 }
1379
1363 if (first_changed > 0) 1380 if (first_changed > 0)
1364 { 1381 {
1365 changed_lines_buf(buf, first_changed, last_changed + 1, 0); 1382 changed_lines_buf(buf, first_changed, last_changed + 1, 0);
1366 redraw_buf_later(buf, VALID); 1383 redraw_buf_later(buf, VALID);
1384 }
1385
1386 if (did_remove_text)
1387 {
1388 garray_T *gap = &buf->b_textprop_text;
1389
1390 // Reduce the growarray size for NULL pointers at the end.
1391 while (gap->ga_len > 0
1392 && ((char_u **)gap->ga_data)[gap->ga_len - 1] == NULL)
1393 --gap->ga_len;
1367 } 1394 }
1368 } 1395 }
1369 1396
1370 /* 1397 /*
1371 * Common for f_prop_type_add() and f_prop_type_change(). 1398 * Common for f_prop_type_add() and f_prop_type_change().