This file is indexed.

/usr/share/parley/plugins/mwclient/upload.py is in parley-data 4:15.12.3-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import random
from cStringIO import StringIO

class Upload(object):
	"""
	Base class for upload objects. This class should always be subclassed 
	by upload classes and its constructor always be called.
	
	Upload classes are file like object/iterators that have additional 
	variables length and content_type.
	"""
	
	BLOCK_SIZE = 8192
	def __init__(self, length, content_type):
		self.length = length
		self.content_type = content_type
		
	def __iter__(self):
		return self
	def next(self):
		data = self.read(self.BLOCK_SIZE)
		if data == '':
			raise StopIteration
		return data
		
	@staticmethod
	def encode(s):
		if type(s) is str:
			return s
		elif type(s) is unicode:
			return s.encode('utf-8')
		else:
			return s

class UploadRawData(Upload):
	"""
	This upload class is simply a wrapper around StringIO 
	"""
	def __init__(self, data, content_type = 'application/x-www-form-urlencoded'):
		self.fstr = StringIO(data)
		Upload.__init__(self, len(data), content_type)
	def read(self, length = -1):
		return self.fstr.read(length)
		
		
class UploadDict(UploadRawData):
	"""
	This class creates an x-www-form-urlencoded representation of a dict 
	and then passes it through its parent UploadRawData 
	"""
	def __init__(self, data):
		postdata = '&'.join('%s=%s' % (self.encode(i), self.encode(data[i])) for i in data)
		UploadRawData.__init__(self, postdata)
		
class UploadFile(Upload):
	"""
	This class accepts a file with information and a postdata dictionary
	and creates a multipart/form-data representation from it.
	"""
	STAGE_FILEHEADER = 0
	STAGE_FILE = 1
	STAGE_POSTDATA = 2
	STAGE_FOOTER = 3
	STAGE_DONE = 4
	def __init__(self, filefield, filename, filelength, file, data):
		self.stage = self.STAGE_FILEHEADER;
		self.boundary = self.generate_boundary()
		self.postdata = self.generate_multipart_from_dict(data)
		self.footer = '\r\n--%s--\r\n' % self.boundary
		self.fileheader = ('--%s\r\n' % self.boundary +
				'Content-Disposition: form-data; name="%s"; filename="%s"\r\n' %
					(self.encode(filefield), self.encode(filename)) +
				'Content-Type: application/octet-stream\r\n\r\n')
		self.file = file
		self.length_left = filelength
		self.str_data = None
		
		Upload.__init__(self, len(self.fileheader) + filelength + len(self.postdata) + len(self.footer) + 2,
			'multipart/form-data; boundary=' + self.boundary)
		
	def read(self, length):
		if self.stage == self.STAGE_DONE:
			return ''
		elif self.stage != self.STAGE_FILE:	
			if self.str_data is None:
				if self.stage == self.STAGE_FILEHEADER:
					self.str_data = StringIO(self.fileheader)
				elif self.stage == self.STAGE_POSTDATA:
					self.str_data = StringIO(self.postdata)
				elif self.stage == self.STAGE_FOOTER:
					self.str_data = StringIO(self.footer)
			data = self.str_data.read(length)
		else:
			if self.length_left:
				if length > self.length_left:
					length = self.length_left
				data = self.file.read(length)
				self.length_left -= len(data)
			else:
				self.stage += 1
				return '\r\n'
		
		if data == '':
			self.stage += 1
			self.str_data = None
			return self.read(length)
		return data

		
	@staticmethod
	def generate_boundary():
		return '----%s----' % ''.join((random.choice(
			'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') 
			for i in xrange(32)))
	
	def generate_multipart_from_dict(self, data):
		postdata = []
		for i in data:
			postdata.append('--' + self.boundary) 
			postdata.append('Content-Disposition: form-data; name="%s"' % self.encode(i))
			postdata.append('')
			postdata.append(self.encode(data[i]))
		return '\r\n'.join(postdata)