Bug 315246 - kate-ctags sometimes fails to find all occurrences of a tag in tagfile
Summary: kate-ctags sometimes fails to find all occurrences of a tag in tagfile
Status: RESOLVED FIXED
Alias: None
Product: kate
Classification: Applications
Component: general (show other bugs)
Version: Git
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: KWrite Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-02-15 23:50 UTC by Aleksandar Radovanovic
Modified: 2013-02-17 19:53 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In: 4.10.1


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Aleksandar Radovanovic 2013-02-15 23:50:00 UTC
Looking up a tag that occurs multiple times in the ctags database (e.g. a function definition and a prototype) sometimes results in only the first (or a first few) occurrence being returned, but not all. 

The problem happens randomly and is not straightforward to reproduce. It is an invalid pointer dereference in kate/plugins/kate-ctags/tags.cpp. See additional information below.

Due to the nature of the bug, it could potentially cause kate to crash, but I've not been able to trigger this so far.

Reproducible: Sometimes

Steps to Reproduce:
1. Enable kate-ctags plugin
2. Create a ctags database that contains multiple instances of the same tag (preferably, 6-7)
3. Point kate-ctags to that database
4. Try to lookup the tag - try several prefixes of varying lengths
Actual Results:  
Sometimes, only the first tag from the ctags index gets returned. Sometimes, more than one, but not all.

Expected Results:  
All tags from the index should be returned.

The problem is in kate/plugins/kate-ctags/tags.cpp, methods Tags::numberOfMatches() and Tags::getMatches(), in the following bit of code (abbreviated for clarity):

	if ( ctags::tagsFind( file, &entry, tagpart.toLocal8Bit(), ...
	{
		do
		{
			...
		}
		while ( ctags::tagsFindNext( file, &entry ) == ctags::TagSuccess );
	}

tagpart.toLocal8Bit() creates a temporary QByteArray object, which is converted to const char * and passed to ctags::tagsFind. However, ctags::tagsFind internally stores this pointer inside the tagFile structure, for later re-use by findNext. But, by the time findNext is called, this temporary is destroyed and the pointer is no longer valid, so findNext randomly fails.

This QByteArray should really be pulled out of the function call, like so:

	QByteArray name = tagpart.toLocal8Bit();
	if ( ctags::tagsFind( file, &entry, name, ...
	{

which solves the problem. I can provide a (tested) patch, if necessary.
Comment 1 Aleksandar Radovanovic 2013-02-15 23:56:49 UTC
Small correction, findNext above should read tagsFindNext
Comment 2 Kåre Särs 2013-02-17 14:51:36 UTC
Git commit ac4c8c5a069ff944f1e66c27635f0ae1e344d52e by Kåre Särs.
Committed on 17/02/2013 at 15:47.
Pushed by sars into branch 'KDE/4.10'.

Fix searching multiple ctags tags
Thanks to Aleksandar Radovanovic for finding the problem and the root cause :)

M  +4    -2    kate/plugins/kate-ctags/tags.cpp

http://commits.kde.org/kate/ac4c8c5a069ff944f1e66c27635f0ae1e344d52e
Comment 3 Kåre Särs 2013-02-17 14:52:22 UTC
Git commit 9d66f2ed487921ea01435072a6442b2766c5f534 by Kåre Särs.
Committed on 17/02/2013 at 15:47.
Pushed by sars into branch 'master'.

Fix searching multiple ctags tags
Thanks to Aleksandar Radovanovic for finding the problem and the root cause :)

M  +4    -2    kate/plugins/kate-ctags/tags.cpp

http://commits.kde.org/kate/9d66f2ed487921ea01435072a6442b2766c5f534
Comment 4 Kåre Särs 2013-02-17 19:53:40 UTC
Aleksandar:
With a patch you see the proposed changes quickly. Thanks again :)

Dominik:
Thanks fo updating the Fixed-in