Mercurial > vim
annotate runtime/ftplugin/debchangelog.vim @ 34603:02fbe0bd9418 v9.1.0193
patch 9.1.0193: May leak memory in completion when ga_grow() fails
Commit: https://github.com/vim/vim/commit/70e566b0bd29189b1baf3dc915b6a98de36fbded
Author: zeertzjq <zeertzjq@outlook.com>
Date: Thu Mar 21 07:11:58 2024 +0100
patch 9.1.0193: May leak memory in completion when ga_grow() fails
Problem: May leak memory in completion when ga_grow() fails.
Solution: Free "wca" when ga_grow() fails (zeertzjq).
fixes: #14248
closes: #14249
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 21 Mar 2024 07:15:05 +0100 |
parents | c6d5af39dc7f |
children |
rev | line source |
---|---|
1620 | 1 " Vim filetype plugin file (GUI menu, folding and completion) |
2152 | 2 " Language: Debian Changelog |
29533 | 3 " Maintainer: Debian Vim Maintainers <team+vim@tracker.debian.org> |
2152 | 4 " Former Maintainers: Michael Piefel <piefel@informatik.hu-berlin.de> |
5 " Stefano Zacchiroli <zack@debian.org> | |
33670
c6d5af39dc7f
runtime(debian): update debian related runtime files (#13423)
Christian Brabandt <cb@256bit.org>
parents:
32974
diff
changeset
|
6 " Last Change: 2023 Aug 18 |
3312 | 7 " License: Vim License |
31885 | 8 " URL: https://salsa.debian.org/vim-team/vim-debian/blob/main/ftplugin/debchangelog.vim |
848 | 9 |
1668 | 10 " Bug completion requires apt-listbugs installed for Debian packages or |
2152 | 11 " python-launchpadlib installed for Ubuntu packages |
1668 | 12 |
13857 | 13 if exists('b:did_ftplugin') |
848 | 14 finish |
15 endif | |
1121 | 16 let b:did_ftplugin=1 |
848 | 17 |
18 " {{{1 Local settings (do on every load) | |
13857 | 19 if exists('g:debchangelog_fold_enable') |
1620 | 20 setlocal foldmethod=expr |
21 setlocal foldexpr=DebGetChangelogFold(v:lnum) | |
22 setlocal foldtext=DebChangelogFoldText() | |
23 endif | |
848 | 24 |
25 " Debian changelogs are not supposed to have any other text width, | |
26 " so the user cannot override this setting | |
27 setlocal tw=78 | |
28 setlocal comments=f:* | |
29 | |
30 " Clean unloading | |
13857 | 31 let b:undo_ftplugin = 'setlocal tw< comments< foldmethod< foldexpr< foldtext<' |
848 | 32 " }}}1 |
7 | 33 |
13857 | 34 if exists('g:did_changelog_ftplugin') |
7 | 35 finish |
36 endif | |
37 | |
31885 | 38 " Don't load another plugin (this is global) |
39 let g:did_changelog_ftplugin = 1 | |
40 | |
29533 | 41 " Make sure the '<' and 'C' flags are not included in 'cpoptions', otherwise |
42 " <CR> would not be recognized. See ":help 'cpoptions'". | |
43 let s:cpo_save = &cpo | |
44 set cpo&vim | |
45 | |
844 | 46 " {{{1 GUI menu |
47 | |
7 | 48 " Helper functions returning various data. |
49 " Returns full name, either from $DEBFULLNAME or debianfullname. | |
50 " TODO Is there a way to determine name from anywhere else? | |
51 function <SID>FullName() | |
13857 | 52 if exists('$DEBFULLNAME') |
7 | 53 return $DEBFULLNAME |
13857 | 54 elseif exists('g:debianfullname') |
7 | 55 return g:debianfullname |
56 else | |
13857 | 57 return 'Your Name' |
7 | 58 endif |
59 endfunction | |
60 | |
61 " Returns email address, from $DEBEMAIL, $EMAIL or debianemail. | |
62 function <SID>Email() | |
13857 | 63 if exists('$DEBEMAIL') |
7 | 64 return $DEBEMAIL |
13857 | 65 elseif exists('$EMAIL') |
7 | 66 return $EMAIL |
13857 | 67 elseif exists('g:debianemail') |
481 | 68 return g:debianemail |
7 | 69 else |
13857 | 70 return 'your@email.address' |
7 | 71 endif |
72 endfunction | |
73 | |
74 " Returns date in RFC822 format. | |
75 function <SID>Date() | |
76 let savelang = v:lc_time | |
13857 | 77 execute 'language time C' |
78 let dateandtime = strftime('%a, %d %b %Y %X %z') | |
79 execute 'language time ' . savelang | |
7 | 80 return dateandtime |
81 endfunction | |
82 | |
83 function <SID>WarnIfNotUnfinalised() | |
13857 | 84 if match(getline('.'), ' -- [[:alpha:]][[:alnum:].]')!=-1 |
7 | 85 echohl WarningMsg |
13857 | 86 echo 'The entry has not been unfinalised before editing.' |
7 | 87 echohl None |
88 return 1 | |
89 endif | |
90 return 0 | |
91 endfunction | |
92 | |
93 function <SID>Finalised() | |
13857 | 94 let savelinenum = line('.') |
95 1 | |
96 call search('^ -- ') | |
97 if match(getline('.'), ' -- [[:alpha:]][[:alnum:].]')!=-1 | |
7 | 98 let returnvalue = 1 |
99 else | |
100 let returnvalue = 0 | |
101 endif | |
102 execute savelinenum | |
103 return returnvalue | |
104 endfunction | |
105 | |
106 " These functions implement the menus | |
107 function NewVersion() | |
108 " The new entry is unfinalised and shall be changed | |
29533 | 109 amenu disable &Changelog.&New\ Version |
110 amenu enable &Changelog.&Add\ Entry | |
111 amenu enable &Changelog.&Close\ Bug | |
112 amenu enable &Changelog.Set\ &Distribution | |
113 amenu enable &Changelog.Set\ &Urgency | |
114 amenu disable &Changelog.U&nfinalise | |
115 amenu enable &Changelog.&Finalise | |
848 | 116 call append(0, substitute(getline(1), '-\([[:digit:]]\+\))', '-$$\1)', '')) |
13857 | 117 call append(1, '') |
118 call append(2, '') | |
119 call append(3, ' -- ') | |
120 call append(4, '') | |
121 call Urgency('low') | |
122 normal! 1G0 | |
123 call search(')') | |
124 normal! h | |
32974
d46f974fd69e
runtime: Fix typos in various files
Christian Brabandt <cb@256bit.org>
parents:
31885
diff
changeset
|
125 " ':normal' doesn't support key annotation (<c-a>) directly. |
29533 | 126 " Vim's manual recommends using ':exe' to use key annotation indirectly (backslash-escaping needed though). |
127 exe "normal! \<c-a>" | |
848 | 128 call setline(1, substitute(getline(1), '-\$\$', '-', '')) |
13857 | 129 if exists('g:debchangelog_fold_enable') |
1668 | 130 foldopen |
131 endif | |
7 | 132 call AddEntry() |
133 endfunction | |
134 | |
135 function AddEntry() | |
13857 | 136 1 |
137 call search('^ -- ') | |
138 .-2 | |
139 call append('.', ' * ') | |
140 .+3 | |
7 | 141 let warn=<SID>WarnIfNotUnfinalised() |
13857 | 142 .-2 |
7 | 143 if warn |
144 echohl MoreMsg | |
13857 | 145 call input('Hit ENTER') |
7 | 146 echohl None |
147 endif | |
148 startinsert! | |
149 endfunction | |
150 | |
151 function CloseBug() | |
13857 | 152 1 |
153 call search('^ -- ') | |
7 | 154 let warn=<SID>WarnIfNotUnfinalised() |
13857 | 155 .-2 |
156 call append('.', ' * (closes: #' . input('Bug number to close: ') . ')') | |
157 normal! j^ll | |
7 | 158 startinsert |
159 endfunction | |
160 | |
161 function Distribution(dist) | |
13857 | 162 call setline(1, substitute(getline(1), ') *\%(UNRELEASED\|\l\+\);', ') ' . a:dist . ';', '')) |
7 | 163 endfunction |
164 | |
165 function Urgency(urg) | |
13857 | 166 call setline(1, substitute(getline(1), 'urgency=.*$', 'urgency=' . a:urg, '')) |
7 | 167 endfunction |
168 | |
169 function <SID>UnfinaliseMenu() | |
170 " This means the entry shall be changed | |
29533 | 171 amenu disable &Changelog.&New\ Version |
172 amenu enable &Changelog.&Add\ Entry | |
173 amenu enable &Changelog.&Close\ Bug | |
174 amenu enable &Changelog.Set\ &Distribution | |
175 amenu enable &Changelog.Set\ &Urgency | |
176 amenu disable &Changelog.U&nfinalise | |
177 amenu enable &Changelog.&Finalise | |
7 | 178 endfunction |
179 | |
180 function Unfinalise() | |
181 call <SID>UnfinaliseMenu() | |
13857 | 182 1 |
183 call search('^ -- ') | |
184 call setline('.', ' -- ') | |
7 | 185 endfunction |
186 | |
187 function <SID>FinaliseMenu() | |
188 " This means the entry should not be changed anymore | |
29533 | 189 amenu enable &Changelog.&New\ Version |
190 amenu disable &Changelog.&Add\ Entry | |
191 amenu disable &Changelog.&Close\ Bug | |
192 amenu disable &Changelog.Set\ &Distribution | |
193 amenu disable &Changelog.Set\ &Urgency | |
194 amenu enable &Changelog.U&nfinalise | |
195 amenu disable &Changelog.&Finalise | |
7 | 196 endfunction |
197 | |
198 function Finalise() | |
199 call <SID>FinaliseMenu() | |
13857 | 200 1 |
201 call search('^ -- ') | |
202 call setline('.', ' -- ' . <SID>FullName() . ' <' . <SID>Email() . '> ' . <SID>Date()) | |
7 | 203 endfunction |
204 | |
205 | |
206 function <SID>MakeMenu() | |
207 amenu &Changelog.&New\ Version :call NewVersion()<CR> | |
29533 | 208 amenu &Changelog.&Add\ Entry :call AddEntry()<CR> |
209 amenu &Changelog.&Close\ Bug :call CloseBug()<CR> | |
210 menu &Changelog.-sep- <nul> | |
7 | 211 |
29533 | 212 amenu &Changelog.Set\ &Distribution.&unstable :call Distribution("unstable")<CR> |
213 amenu &Changelog.Set\ &Distribution.&frozen :call Distribution("frozen")<CR> | |
214 amenu &Changelog.Set\ &Distribution.&stable :call Distribution("stable")<CR> | |
215 menu &Changelog.Set\ &Distribution.-sep- <nul> | |
216 amenu &Changelog.Set\ &Distribution.frozen\ unstable :call Distribution("frozen unstable")<CR> | |
217 amenu &Changelog.Set\ &Distribution.stable\ unstable :call Distribution("stable unstable")<CR> | |
218 amenu &Changelog.Set\ &Distribution.stable\ frozen :call Distribution("stable frozen")<CR> | |
219 amenu &Changelog.Set\ &Distribution.stable\ frozen\ unstable :call Distribution("stable frozen unstable")<CR> | |
7 | 220 |
29533 | 221 amenu &Changelog.Set\ &Urgency.&low :call Urgency("low")<CR> |
222 amenu &Changelog.Set\ &Urgency.&medium :call Urgency("medium")<CR> | |
223 amenu &Changelog.Set\ &Urgency.&high :call Urgency("high")<CR> | |
7 | 224 |
29533 | 225 menu &Changelog.-sep- <nul> |
226 amenu &Changelog.U&nfinalise :call Unfinalise()<CR> | |
227 amenu &Changelog.&Finalise :call Finalise()<CR> | |
7 | 228 |
229 if <SID>Finalised() | |
230 call <SID>FinaliseMenu() | |
231 else | |
232 call <SID>UnfinaliseMenu() | |
233 endif | |
234 endfunction | |
235 | |
236 augroup changelogMenu | |
237 au BufEnter * if &filetype == "debchangelog" | call <SID>MakeMenu() | endif | |
29533 | 238 au BufLeave * if &filetype == "debchangelog" | silent! aunmenu &Changelog | endif |
7 | 239 augroup END |
240 | |
844 | 241 " }}} |
242 " {{{1 folding | |
243 | |
1121 | 244 " look for an author name in the [zonestart zoneend] lines searching backward |
245 function! s:getAuthor(zonestart, zoneend) | |
246 let linepos = a:zoneend | |
247 while linepos >= a:zonestart | |
248 let line = getline(linepos) | |
13857 | 249 if line =~# '^ --' |
1121 | 250 return substitute(line, '^ --\s*\([^<]\+\)\s*.*', '\1', '') |
251 endif | |
252 let linepos -= 1 | |
844 | 253 endwhile |
1121 | 254 return '[unknown]' |
844 | 255 endfunction |
256 | |
1620 | 257 " Look for a package source name searching backward from the givenline and |
258 " returns it. Return the empty string if the package name can't be found | |
259 function! DebGetPkgSrcName(lineno) | |
260 let lineidx = a:lineno | |
261 let pkgname = '' | |
262 while lineidx > 0 | |
263 let curline = getline(lineidx) | |
13857 | 264 if curline =~# '^\S' |
1620 | 265 let pkgname = matchlist(curline, '^\(\S\+\).*$')[1] |
266 break | |
267 endif | |
268 let lineidx = lineidx - 1 | |
269 endwhile | |
270 return pkgname | |
271 endfunction | |
272 | |
844 | 273 function! DebChangelogFoldText() |
13857 | 274 if v:folddashes ==# '-' " changelog entry fold |
1121 | 275 return foldtext() . ' -- ' . s:getAuthor(v:foldstart, v:foldend) . ' ' |
844 | 276 endif |
277 return foldtext() | |
278 endfunction | |
279 | |
1620 | 280 function! DebGetChangelogFold(lnum) |
844 | 281 let line = getline(a:lnum) |
13857 | 282 if line =~# '^\w\+' |
844 | 283 return '>1' " beginning of a changelog entry |
284 endif | |
13857 | 285 if line =~# '^\s\+\[.*\]' |
844 | 286 return '>2' " beginning of an author-specific chunk |
287 endif | |
13857 | 288 if line =~# '^ --' |
844 | 289 return '1' |
290 endif | |
291 return '=' | |
292 endfunction | |
293 | |
13857 | 294 if exists('g:debchangelog_fold_enable') |
1668 | 295 silent! foldopen! " unfold the entry the cursor is on (usually the first one) |
296 endif | |
1620 | 297 |
298 " }}} | |
299 | |
300 " {{{1 omnicompletion for Closes: # | |
301 | |
302 if !exists('g:debchangelog_listbugs_severities') | |
303 let g:debchangelog_listbugs_severities = 'critical,grave,serious,important,normal,minor,wishlist' | |
304 endif | |
305 | |
306 fun! DebCompleteBugs(findstart, base) | |
307 if a:findstart | |
308 let line = getline('.') | |
1668 | 309 |
310 " try to detect whether this is closes: or lp: | |
311 let g:debchangelog_complete_mode = 'debbugs' | |
312 let try_colidx = col('.') - 1 | |
313 let colidx = -1 " default to no-completion-possible | |
314 | |
13857 | 315 while try_colidx > 0 && line[try_colidx - 1] =~# '\s\|\d\|#\|,\|:' |
1668 | 316 let try_colidx = try_colidx - 1 |
13857 | 317 if line[try_colidx] ==# '#' && colidx == -1 |
1668 | 318 " found hash, where we complete from: |
319 let colidx = try_colidx | |
13857 | 320 elseif line[try_colidx] ==# ':' |
321 if try_colidx > 1 && strpart(line, try_colidx - 2, 3) =~? '\clp:' | |
1668 | 322 let g:debchangelog_complete_mode = 'lp' |
323 endif | |
324 break | |
325 endif | |
326 endwhile | |
327 return colidx | |
328 else " return matches: | |
329 let bug_lines = [] | |
13857 | 330 if g:debchangelog_complete_mode ==? 'lp' |
1668 | 331 if ! has('python') |
332 echoerr 'vim must be built with Python support to use LP bug completion' | |
333 return | |
334 endif | |
335 let pkgsrc = DebGetPkgSrcName(line('.')) | |
336 python << EOF | |
337 import vim | |
338 try: | |
2152 | 339 from launchpadlib.launchpad import Launchpad |
340 from lazr.restfulclient.errors import HTTPError | |
341 # login anonymously | |
342 lp = Launchpad.login_anonymously('debchangelog.vim', 'production') | |
343 ubuntu = lp.distributions['ubuntu'] | |
344 try: | |
345 sp = ubuntu.getSourcePackage(name=vim.eval('pkgsrc')) | |
346 status = ('New', 'Incomplete', 'Confirmed', 'Triaged', | |
347 'In Progress', 'Fix Committed') | |
348 tasklist = sp.searchTasks(status=status, order_by='id') | |
349 liststr = '[' | |
350 for task in tasklist: | |
351 bug = task.bug | |
352 liststr += "'#%d - %s'," % (bug.id, bug.title.replace('\'', '\'\'')) | |
353 liststr += ']' | |
354 vim.command('silent let bug_lines = %s' % liststr.encode('utf-8')) | |
355 except HTTPError: | |
356 pass | |
1668 | 357 except ImportError: |
2152 | 358 vim.command('echoerr \'python-launchpadlib >= 1.5.4 needs to be installed to use Launchpad bug completion\'') |
1668 | 359 EOF |
1620 | 360 else |
1668 | 361 if ! filereadable('/usr/sbin/apt-listbugs') |
362 echoerr 'apt-listbugs not found, you should install it to use Closes bug completion' | |
363 return | |
364 endif | |
365 let pkgsrc = DebGetPkgSrcName(line('.')) | |
366 let listbugs_output = system('/usr/sbin/apt-listbugs -s ' . g:debchangelog_listbugs_severities . ' list ' . pkgsrc . ' | grep "^ #" 2> /dev/null') | |
367 let bug_lines = split(listbugs_output, '\n') | |
1620 | 368 endif |
369 let completions = [] | |
370 for line in bug_lines | |
371 let parts = matchlist(line, '^\s*\(#\S\+\)\s*-\s*\(.*\)$') | |
1668 | 372 " filter only those which match a:base: |
13857 | 373 if parts[1] !~ '^' . a:base |
1668 | 374 continue |
375 endif | |
1620 | 376 let completion = {} |
377 let completion['word'] = parts[1] | |
378 let completion['menu'] = parts[2] | |
379 let completion['info'] = parts[0] | |
380 let completions += [completion] | |
381 endfor | |
382 return completions | |
383 endif | |
384 endfun | |
385 | |
386 setlocal omnifunc=DebCompleteBugs | |
1121 | 387 |
844 | 388 " }}} |
389 | |
29533 | 390 " Restore the previous value of 'cpoptions'. |
391 let &cpo = s:cpo_save | |
392 unlet s:cpo_save | |
393 | |
844 | 394 " vim: set foldmethod=marker: |