[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#275847: python-apt: segfault on bad usage of ParseTagFile



Package: python-apt
Version: 0.5.10
Severity: normal


If you fail to use parse.step() on parsing a tag file,
instead of getting an exception, the .so segfaults.

Attached is an example program that does this.

-- System Information:
Debian Release: 3.1
  APT prefers experimental
  APT policy: (990, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.7-1-686
Locale: LANG=C, LC_CTYPE=C (ignored: LC_ALL set to ga_IE.UTF-8)

Versions of packages python-apt depends on:
ii  apt [libapt-pkg-libc6.3-5-3 0.5.27       Advanced front-end for dpkg
ii  apt-utils [libapt-inst-libc 0.5.27       APT utility programs
ii  libc6                       2.3.2.ds1-17 GNU C Library: Shared libraries an
ii  python                      2.3.4-4      An interactive high-level object-o

-- no debconf information
#!/usr/bin/python
# -*- coding: UTF-8 -*-

__author__ = 'Alastair McKinstry'
__author_email__ = 'mckinstry@debian.org'
__copyright__ = 'Copyright © 2004 Alastair McKinstry <mckinstry@debian.org>'
__license__ = 'GPL'
__version__ = '$Id$'

import apt_pkg, os, unittest, errno
# from errno import *

__all__ = [ 'Archive', 'Distribution' ]

class BadDistribution(Exception):
	pass

class Archive:
	"""Class for Debian Archive management"""

	__archives = {}
	def __init__(self, path):
		"""Create an archive object listing the archives, as necessary """
		if self.__archives.has_key(path):
			a = self.__archives[path]
			self.__dict__ = a.__dict__
			self.__class__ = a.__class__
		else:
			self.path = path
			self.dists = {}
			self.Distributions = os.listdir('%s/dists' % path)
			self.__archives[path] = self
			self._dists_fetched = False
	def fetchDistributions(self):
		"""Fetch all the distribution details, and eliminate aliases"""
		for d in self.Distributions:
			try:
				di = Distribution(self, d)
			except BadDistribution, e:
				# Remove d from list
				pass
	
class Distribution:
	"""Class for Distribution within Debian Archive"""

	__distributions = {}

	# Tags that may be in a release file.
	# Not interested in MD5Sum for the moment.
	_tags = ['Origin', 'Label', 'Suite', 'Codename', 'Date', 
		'Architectures', 'Components', 'Description', 'Version']

	def __init__(self, archive, name):
		"""Create a Distribution object, from an archive"""
		if self.__distributions.has_key((archive, name)):
			a = self.__distributions[archive, name]
			self.__dict__ = a.__dict__
			self.__class__ = a.__class__
		else:
			self.archive = archive
			self.name = name
			try:
				path = '%s/dists/%s/Release' % (archive.path, name)
				f = open(path, 'r')
			except IOError, e:
				print e.__dict__
				if e.errno == errno.ENOENT or e.errno == errno.ENOTDIR:
					raise BadDistribution, '%s is not a distibution name' % name
				raise IOError, e
			try:
				parse = apt_pkg.ParseTagFile(open(path,'r'))
			except:	
				raise SystemError, "Failed to parse file %s" % path
			for tag in self._tags:
				val = parse.Section.get(tag)
				if val != '':
					setattr(self, tag, val)
	
		
class ArchiveTestCase(unittest.TestCase):
	"""Unit tests for Debian Archive class"""
	def testArchive(self):
		"""Test Creation"""
		a = Archive('/srv/debian.org/debian')
	def testSingleton(self):
		"""Check that archives are cached."""
		a = Archive('/srv/debian.org/debian')
		b = Archive('/srv/debian.org/debian')
		assert id(a.__dict__) == id(b.__dict__), "Archive objects not cached"
	def testDistributions(self):
		"""Check we get the correct distributions"""
		a = Archive('/srv/debian.org/debian')
		a.fetchDistributions()
		

class DistributionTestCase(unittest.TestCase):
	"""Unit Tests for Debian Distribution class"""
	def testDistribution(self):
		"""Create a distribution object"""
		archive = Archive('/srv/debian.org/debian')
		dist = Distribution(archive, 'woody')
	
if __name__ == '__main__':
	unittest.main()

Reply to: