Skip to content

Commit

Permalink
Fix IndexError caused by invalid tags (#348)
Browse files Browse the repository at this point in the history
`TagFile` class' __getitem__() method returns `Tag` objects for invalid tags
with only one column or even for empty lines. This causes index errors, when
trying to access non-existing columns (not enough \t present in a line).
  • Loading branch information
deathaxe committed Jan 6, 2024
1 parent 9468e67 commit f029530
Showing 1 changed file with 23 additions and 11 deletions.
34 changes: 23 additions & 11 deletions ctags.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,16 +393,26 @@ def __init__(self, line, column=0):
self.column = column

def __lt__(self, other):
return self.line.split('\t')[self.column] < other
try:
return self.key < other
except IndexError:
return False

def __gt__(self, other):
return self.line.split('\t')[self.column] > other
try:
return self.key > other
except IndexError:
return False

def __getitem__(self, index):
return self.line.split('\t')[index]
return self.line.split('\t', self.column + 1)[index]

def __len__(self):
return len(self.line.split('\t'))
return self.line.count('\t') + 1

@property
def key(self):
return self[self.column]

class TagFile(object):
"""
Expand Down Expand Up @@ -443,6 +453,8 @@ def __getitem__(self, index):
result = self.mapped.readline() # get a complete line

result = result.strip()
if not result:
raise IndexError("Invalid tag at index %d." % index)

return Tag(result, self.column)

Expand Down Expand Up @@ -500,20 +512,21 @@ def search(self, exact_match=True, *tags):
if not tags:
while self.mapped.tell() < self.mapped.size():
result = Tag(self.mapped.readline().strip(), self.column)
yield(result)
if result.line:
yield result
return

for key in tags:
left_index = bisect.bisect_left(self, key)
if exact_match:
result = self[left_index]
while result.line and result[result.column] == key:
yield(result)
yield result
result = Tag(self.mapped.readline().strip(), self.column)
else:
result = self[left_index]
while result.line and result[result.column].startswith(key):
yield(result)
yield result
result = Tag(self.mapped.readline().strip(), self.column)

def search_by_suffix(self, suffix):
Expand All @@ -529,10 +542,9 @@ def search_by_suffix(self, suffix):
:returns: matching tags
"""
for line in self.file_o:
if line.split('\t')[self.column].endswith(suffix):
yield Tag(line)
else:
continue
tag = Tag(line, self.column)
if tag.key.endswith(suffix):
yield tag

def tag_class(self):
"""
Expand Down

0 comments on commit f029530

Please sign in to comment.