Mercurial > vim
comparison src/json.c @ 21275:c14e628cd4bb v8.2.1188
patch 8.2.1188: memory leak with invalid json input
Commit: https://github.com/vim/vim/commit/6d3a7213f58da834b0fc869d05f87e86010c66cf
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jul 12 14:34:00 2020 +0200
patch 8.2.1188: memory leak with invalid json input
Problem: Memory leak with invalid json input.
Solution: Free all keys at the end. (Dominique Pell?, closes https://github.com/vim/vim/issues/6443,
closes #6442)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 12 Jul 2020 14:45:03 +0200 |
parents | 9064044fd4f6 |
children | 4dfd00f481fb |
comparison
equal
deleted
inserted
replaced
21274:f7f5e51a629b | 21275:c14e628cd4bb |
---|---|
592 */ | 592 */ |
593 static int | 593 static int |
594 json_decode_item(js_read_T *reader, typval_T *res, int options) | 594 json_decode_item(js_read_T *reader, typval_T *res, int options) |
595 { | 595 { |
596 char_u *p; | 596 char_u *p; |
597 int i; | |
597 int len; | 598 int len; |
598 int retval; | 599 int retval; |
599 garray_T stack; | 600 garray_T stack; |
600 typval_T item; | 601 typval_T item; |
601 typval_T *cur_item; | 602 typval_T *cur_item; |
619 json_skip_white(reader); | 620 json_skip_white(reader); |
620 p = reader->js_buf + reader->js_used; | 621 p = reader->js_buf + reader->js_used; |
621 if (*p == NUL) | 622 if (*p == NUL) |
622 { | 623 { |
623 retval = MAYBE; | 624 retval = MAYBE; |
624 if (top_item->jd_type == JSON_OBJECT) | |
625 // did get the key, clear it | |
626 clear_tv(&top_item->jd_key_tv); | |
627 goto theend; | 625 goto theend; |
628 } | 626 } |
629 if (top_item->jd_type == JSON_OBJECT_KEY | 627 if (top_item->jd_type == JSON_OBJECT_KEY |
630 || top_item->jd_type == JSON_ARRAY) | 628 || top_item->jd_type == JSON_ARRAY) |
631 { | 629 { |
923 && cur_item != NULL) | 921 && cur_item != NULL) |
924 { | 922 { |
925 top_item->jd_key = tv_get_string_buf_chk(cur_item, key_buf); | 923 top_item->jd_key = tv_get_string_buf_chk(cur_item, key_buf); |
926 if (top_item->jd_key == NULL) | 924 if (top_item->jd_key == NULL) |
927 { | 925 { |
928 clear_tv(cur_item); | |
929 emsg(_(e_invarg)); | 926 emsg(_(e_invarg)); |
930 retval = FAIL; | 927 retval = FAIL; |
931 goto theend; | 928 goto theend; |
932 } | 929 } |
933 } | 930 } |
999 && dict_find(top_item->jd_tv.vval.v_dict, | 996 && dict_find(top_item->jd_tv.vval.v_dict, |
1000 top_item->jd_key, -1) != NULL) | 997 top_item->jd_key, -1) != NULL) |
1001 { | 998 { |
1002 semsg(_("E938: Duplicate key in JSON: \"%s\""), | 999 semsg(_("E938: Duplicate key in JSON: \"%s\""), |
1003 top_item->jd_key); | 1000 top_item->jd_key); |
1004 clear_tv(&top_item->jd_key_tv); | |
1005 clear_tv(cur_item); | 1001 clear_tv(cur_item); |
1006 retval = FAIL; | 1002 retval = FAIL; |
1007 goto theend; | 1003 goto theend; |
1008 } | 1004 } |
1009 | 1005 |
1058 res->vval.v_number = VVAL_NONE; | 1054 res->vval.v_number = VVAL_NONE; |
1059 } | 1055 } |
1060 semsg(_(e_json_error), p); | 1056 semsg(_(e_json_error), p); |
1061 | 1057 |
1062 theend: | 1058 theend: |
1059 for (i = 0; i < stack.ga_len; i++) | |
1060 clear_tv(&(((json_dec_item_T *)stack.ga_data) + i)->jd_key_tv); | |
1063 ga_clear(&stack); | 1061 ga_clear(&stack); |
1062 | |
1064 return retval; | 1063 return retval; |
1065 } | 1064 } |
1066 | 1065 |
1067 /* | 1066 /* |
1068 * Decode the JSON from "reader" and store the result in "res". | 1067 * Decode the JSON from "reader" and store the result in "res". |