Mercurial > vim
comparison src/list.c @ 20657:a1e6d9353736 v8.2.0882
patch 8.2.0882: leaking memory when using reduce()
Commit: https://github.com/vim/vim/commit/48b1c21809553d3463b5ed6c2b3bc6d335663bb6
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jun 1 20:11:02 2020 +0200
patch 8.2.0882: leaking memory when using reduce()
Problem: Leaking memory when using reduce().
Solution: Free the intermediate value.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 01 Jun 2020 20:15:04 +0200 |
parents | 1fa0ace0ba65 |
children | 821925509d8c |
comparison
equal
deleted
inserted
replaced
20656:d9b945841cba | 20657:a1e6d9353736 |
---|---|
2309 * "reduce(list, { accumlator, element -> value } [, initial])" function | 2309 * "reduce(list, { accumlator, element -> value } [, initial])" function |
2310 */ | 2310 */ |
2311 void | 2311 void |
2312 f_reduce(typval_T *argvars, typval_T *rettv) | 2312 f_reduce(typval_T *argvars, typval_T *rettv) |
2313 { | 2313 { |
2314 typval_T accum; | 2314 typval_T initial; |
2315 char_u *func_name; | 2315 char_u *func_name; |
2316 partial_T *partial = NULL; | 2316 partial_T *partial = NULL; |
2317 funcexe_T funcexe; | 2317 funcexe_T funcexe; |
2318 typval_T argv[3]; | 2318 typval_T argv[3]; |
2319 | 2319 |
2341 | 2341 |
2342 if (argvars[0].v_type == VAR_LIST) | 2342 if (argvars[0].v_type == VAR_LIST) |
2343 { | 2343 { |
2344 list_T *l = argvars[0].vval.v_list; | 2344 list_T *l = argvars[0].vval.v_list; |
2345 listitem_T *li = NULL; | 2345 listitem_T *li = NULL; |
2346 int r; | |
2346 | 2347 |
2347 CHECK_LIST_MATERIALIZE(l); | 2348 CHECK_LIST_MATERIALIZE(l); |
2348 if (argvars[2].v_type == VAR_UNKNOWN) | 2349 if (argvars[2].v_type == VAR_UNKNOWN) |
2349 { | 2350 { |
2350 if (l == NULL || l->lv_first == NULL) | 2351 if (l == NULL || l->lv_first == NULL) |
2351 { | 2352 { |
2352 semsg(_(e_reduceempty), "List"); | 2353 semsg(_(e_reduceempty), "List"); |
2353 return; | 2354 return; |
2354 } | 2355 } |
2355 accum = l->lv_first->li_tv; | 2356 initial = l->lv_first->li_tv; |
2356 li = l->lv_first->li_next; | 2357 li = l->lv_first->li_next; |
2357 } | 2358 } |
2358 else | 2359 else |
2359 { | 2360 { |
2360 accum = argvars[2]; | 2361 initial = argvars[2]; |
2361 if (l != NULL) | 2362 if (l != NULL) |
2362 li = l->lv_first; | 2363 li = l->lv_first; |
2363 } | 2364 } |
2364 | 2365 |
2365 copy_tv(&accum, rettv); | 2366 copy_tv(&initial, rettv); |
2366 for ( ; li != NULL; li = li->li_next) | 2367 for ( ; li != NULL; li = li->li_next) |
2367 { | 2368 { |
2368 argv[0] = accum; | 2369 argv[0] = *rettv; |
2369 argv[1] = li->li_tv; | 2370 argv[1] = li->li_tv; |
2370 if (call_func(func_name, -1, rettv, 2, argv, &funcexe) == FAIL) | 2371 rettv->v_type = VAR_UNKNOWN; |
2372 r = call_func(func_name, -1, rettv, 2, argv, &funcexe); | |
2373 clear_tv(&argv[0]); | |
2374 if (r == FAIL) | |
2371 return; | 2375 return; |
2372 accum = *rettv; | |
2373 } | 2376 } |
2374 } | 2377 } |
2375 else | 2378 else |
2376 { | 2379 { |
2377 blob_T *b = argvars[0].vval.v_blob; | 2380 blob_T *b = argvars[0].vval.v_blob; |
2382 if (b == NULL || b->bv_ga.ga_len == 0) | 2385 if (b == NULL || b->bv_ga.ga_len == 0) |
2383 { | 2386 { |
2384 semsg(_(e_reduceempty), "Blob"); | 2387 semsg(_(e_reduceempty), "Blob"); |
2385 return; | 2388 return; |
2386 } | 2389 } |
2387 accum.v_type = VAR_NUMBER; | 2390 initial.v_type = VAR_NUMBER; |
2388 accum.vval.v_number = blob_get(b, 0); | 2391 initial.vval.v_number = blob_get(b, 0); |
2389 i = 1; | 2392 i = 1; |
2390 } | 2393 } |
2394 else if (argvars[2].v_type != VAR_NUMBER) | |
2395 { | |
2396 emsg(_(e_number_exp)); | |
2397 return; | |
2398 } | |
2391 else | 2399 else |
2392 { | 2400 { |
2393 accum = argvars[2]; | 2401 initial = argvars[2]; |
2394 i = 0; | 2402 i = 0; |
2395 } | 2403 } |
2396 | 2404 |
2397 copy_tv(&accum, rettv); | 2405 copy_tv(&initial, rettv); |
2398 if (b != NULL) | 2406 if (b != NULL) |
2399 { | 2407 { |
2400 for ( ; i < b->bv_ga.ga_len; i++) | 2408 for ( ; i < b->bv_ga.ga_len; i++) |
2401 { | 2409 { |
2402 argv[0] = accum; | 2410 argv[0] = *rettv; |
2403 argv[1].v_type = VAR_NUMBER; | 2411 argv[1].v_type = VAR_NUMBER; |
2404 argv[1].vval.v_number = blob_get(b, i); | 2412 argv[1].vval.v_number = blob_get(b, i); |
2405 if (call_func(func_name, -1, rettv, 2, argv, &funcexe) == FAIL) | 2413 if (call_func(func_name, -1, rettv, 2, argv, &funcexe) == FAIL) |
2406 return; | 2414 return; |
2407 accum = *rettv; | |
2408 } | 2415 } |
2409 } | 2416 } |
2410 } | 2417 } |
2411 } | 2418 } |
2412 | 2419 |