[Nym3-commit] r38 - trunk

nym3-devel@lists.noreply.org nym3-devel@lists.noreply.org
Thu, 29 Jul 2004 00:11:51 +0200


Author: jr
Date: 2004-07-29 00:11:49 +0200 (Thu, 29 Jul 2004)
New Revision: 38

Modified:
   trunk/Message.py
   trunk/TODO
Log:
added the __str__() method in the CommandCToS classes
added doc string describing the attributes of these classes


Modified: trunk/Message.py
===================================================================
--- trunk/Message.py	2004-07-28 21:02:17 UTC (rev 37)
+++ trunk/Message.py	2004-07-28 22:11:49 UTC (rev 38)
@@ -1,10 +1,14 @@
+import types
+
 class ParseError(Exception):
+	"""ParseError : error raised if anything goes wrong during parsing"""
         def __init__(self,value):
                 self.value=value
         def __str__(self):
                 return repr(self.value)
 
 class BadArgument(Exception):
+	"""BadArgument : error raised if a function is given an irrelevant argument"""
         def __init__(self,value):
                 self.value=value
         def __str__(self):
@@ -29,8 +33,9 @@
 	return aux(n,"",mod)
 
 def isMsgIdList(l):
+	"""true if l is a list of strings of length 20"""
 	def isMsgId(e):
-		if(len(e)==20): # et son type str?
+		if( len(e)==20 and types(e)==types.StringType ):
 			return True
 		else:
 			return False
@@ -53,6 +58,7 @@
             self.a = 0
             self.b = 0
 	def isEnd(self):
+		"""True if we have read the whole string"""
 		return (b == len(s))
         def next(self,n):
 		"""return the next n characters"""
@@ -62,8 +68,12 @@
                 self.b = self.b + n
 		return self.s[self.a:self.b]
 	def readHeader(self):
-		return Header.read(self)
+		"""Read next header from the string"""
+		h=Header()
+		h.fromStrReader(self)
+		return h
 	def readCommandCToS(self):
+		"""Read next CommandCToS from string"""
 		try:
 			ct = ord(self.next(1))
 			cs = strToIntBE(self.next(3))
@@ -89,14 +99,18 @@
 				raise ParseError("Undefined Command Type")
 			a.fromStrReader(self,cs)
 			return a
-		except IndexError:
+		except IndexError: #is it really necessary? is it not considered in the various fromStrReader ?
 			raise ParseError("Bad Formed Command")
 	def readNym(self,start,cs):
+		"""Read a Nym length + a nym
+		Raise ParseError if it takes more characters from the string that previously advertised"""
 		nl = ord (self.next(1))
 		if(self.b + nl - start > cs):
 			raise ParseError("Bad Formed Command")
 		return self.next(nl)
 	def readNymList(self,start,cs):
+		"""Read a list of (Nym length + a nym)
+		Raise ParseError if it takes more characters from the string that previously advertised"""
 		try:
 			l = []
 			while(self.b < start + cs):
@@ -105,10 +119,14 @@
 		except ParseError: #is it really necessary?
 			raise
 	def readMsgId(self,start,cs):
+		"""Read a msgId
+		Raise ParseError if it takes more characters from the string that previously advertised"""
 		if(self.b + msgIdLength - start > cs):
 			raise ParseError("Bad Formed Command")
 		return self.next(msgIdLength)
 	def readMsgIdList(self,start,cs):
+		"""Read a list of msgId
+		Raise ParseError if it takes more characters from the string that previously advertised"""
 		try:
 			l = []
 			while(self.b < start + cs):
@@ -118,6 +136,12 @@
 			raise
 	
 class Header:
+	"""Header Object
+	sig : signature
+	nl : nym length
+	nym : nym
+	seqNo : sequence number which identifies the message
+	length : header length"""
 	def __init__(self):
 		"""Build a Header empty object"""
 		pass
@@ -140,14 +164,11 @@
 		self.seqNo = seqNo
 		#self.length = sigLength + 1 + self.nl + seqNoLength
 	def __str__(self):
+		"""Give the string of the header that would be sent in a control message"""
 		return self.sig + chr(self.nl) + self.nym + self.seqNo
 	def fromStrReader(self,sr):
 		"""Fill a Header from a StrReader 
-		sig : signature
-		nl : nym length
-		nym : nym
-		seqNo : sequence number which identifies the message
-		length : header length"""
+		"""
 		try:
 			self.sig = sr.next(sigLength)
 			self.nl = ord(sr.next(1))
@@ -191,17 +212,27 @@
 ##         self.length = sigLength + 1 + self.nl + seqNoLength
 
 class CommandCToS:
+	"""CommandCToS astract class
+	the CommandCToS derive from this class"""
 	pass
 
 class Create(CommandCToS):
-	"""Create command"""
+	"""Create command
+	self.list : list de nym (liste de str)
+	self.pw : proof of work"""
 	def __init__(self):
 		"""Build a Create empty object"""
 		pass
 	def fromData(self,l,pw=""):
 		"""Fill a Create Object from a list of nyms and a proof of work"""
+		if(len(l)>255):
+			raise BadArgument("Create.fromData : len(l) too big")
+		for i in range(l):
+			if(len(l[i])>255):
+				raise BadArgument("Create.fromData : nym too long")
 		self.list=l
 		self.pw=pw
+		#if len(pw) isn't too big, we are sure that the command size is small enough because of the size and the number of nyms 
 	def fromStrReader(self,sr,cs):
 		"""Fill a Create command from a StrReader
 		raise ParseError if it is malformed"""
@@ -215,45 +246,78 @@
 		#nNym is redundant, we use it to make sure the message is well formed
 		if(nNym != len(self.nymList)):
 		   raise ParseError("Bad Formed Command : Create")
-			
-
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=chr(len(self.list))+self.pw
+		for i in range(len(self.list)):
+			s+chr(len(self.list[i]))+self.list[i]
+		if(len(s)>(256*256*256)): #should not be possible, otherwise, bug
+			raise BadArgument("Create.__str__ : command body too long")
+		return chr(0)+intToStrBE(len(s),3)+s
+		
+		
+		
 class Create2(CommandCToS):
-	"""Create2 command"""
+	"""Create2 command
+	self.cr : challenge response (str)"""
 	def __init__(self):
 		"""Build a Create2 empty object"""
 		pass
 	def fromData(self,cr):
 		"""Fill Create2 from a string containing the response to a challenge"""
 		self.cr=cr
+		#if cr is small enough we are sure that the command size is small enough
 	def fromStrReader(self,sr,cs):
 		"""Fill a Create2 command from a StrReader
 		raise ParseError if it is malformed"""
 		self.cr=sr.next(cs)
-		
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=self.cr
+		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+			raise BadArgument("Create2.__str__ : command body too long")
+		return chr(1)+intToStrBE(len(s),3)+s
+	
 class Surb(CommandCToS):
-	"""Surb command"""
+	"""Surb command
+	self.surbs : set of surbs (str)"""
 	def __init__(self):
 		"""Build a Surb empty object"""
 		pass
 	def fromData(self,s):
 		"""Fill a Surb Object from a string containing Surbs"""
 		self.surbs=s
+		if(len(s)>(256*256*256)):
+			raise BadArgument("Surb.fromData : command body too long")
 	def fromStrReader(self,sr,cs):
 		"""Fill a Surb Object from a StrReader
 		raise ParseError if it is malformed"""
 		if(cs%surbLength != 0):
 			raise ParseError("Bad Formed Command : Surb")
 		self.surbs=sr.next(cs)
-
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=self.surbs
+		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+			raise BadArgument("Surb.__str__ : command body too long")
+		return chr(2)+intToStrBE(len(s),3)+s
+	
 class Newpk(CommandCToS):
-	"""Newpk command"""
+	"""Newpk command
+	self.kid : identity key RSA ASN-1 encoded (str)
+	self.kenc : encryption key RSA ASN-1 encoded (str)"""
 	def __init__(self):
 		"""Build a Newpk empty object"""
 		pass
 	def fromData(self,sid,senc):
 		"""Fill a Newpk Object from 2 strings containing an ASN-1 encoded RSA key"""
+		id_l=len(sid)
+		id_l2=len(senc)
+		if( ((id_l != 128) and (id_l != 256)) or ( (id_l2 != 128) and (id_l2 != 256))):
+			raise BadArgument("Newpk.fromData : sid or senc as not a valid size")
 		self.kid=sid
 		self.kenc=senc
+		#command body is small enough
 	def fromStrReader(self,sr,cs):
 		"""Fill a Newpk Object from a StrReader
 		raise ParseError if it is malformed"""
@@ -261,15 +325,27 @@
 			id_l=strToIntBE(sr.next(2))
 			if( (id_l != 128) and (id_l != 256)):
 				raise ParseError("Bad Formed Command : Newpk")
-			idl_2=cs-2-id_l
+			id_l2=cs-2-id_l
 			if( (id_l2 != 128) and (id_l2 != 256)):
 				raise ParseError("Bad Formed Command : Newpk")
 			self.kid=sr.next(id_l)
 			self.kenc=sr.next(id_l2)
 		except IndexError:
 			raise ParseError("Bad Formed Command : Newpk")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		#TODO check assuming len(kid)=128 or 256
+		s=intToStrBE(len(self.kid),2)+self.kid+self.kenc
+		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+			raise BadArgument("Newpk.__str__ : command body too long")
+		return chr(3)+intToStrBE(len(s),3)+s
+	
 class Relay(CommandCToS):
-	"""Relay command"""
+	"""Relay command
+	self.rs : routing info size (int)
+	self.rt : routing type (str of length 2)
+	self.ri : routing info (str)
+	self.body : body of the message (str)"""
 	def __init__(self):
 		"""Build a Relay empty object"""
 		pass
@@ -279,8 +355,12 @@
 			raise BadArgument("Relay.fromData : RT size isn't 2 bytes")
 		self.rt=rt
 		self.rs=len(ri)
+		if(self.rs > 256*256):
+			raise BadArgument("Relay.fromData : RS size isn't 2 bytes")
 		self.ri=ri
 		self.body=body
+		if(4+self.rs+len(body) > (256*256*256)):
+			raise BadArgument("Relay.fromData : Command body too long")
 	def fromStrReader(self,sr,cs):
 		"""Fill a Relay Object from a StrReader
 		raise ParseError if it is malformed"""
@@ -291,9 +371,16 @@
 			self.body=sr.next(cs-4-self.rs)
 		except (BadArgument, IndexError):
 			raise ParseError("Bad Formed Command : Relay")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
 		
+		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+			raise BadArgument("Relay.__str__ : Command Body too long")
+		return chr(4)+intToStrBE(len(s),3)+s
+	
 class Get(CommandCToS):
-	"""Get command"""
+	"""Get command
+	self.l : list of msgId (list of str of len msgIdLength)"""
 	def __init__(self):
 		"""Build a Get empty object"""
 		pass
@@ -303,6 +390,8 @@
 		if( not isMsgIdList(li)):
 			raise BadArgument("Get.fromData : li is not a list of message id")
 		self.l=li
+		if(msgIdLength*len(self.l)>256*256*256):
+			raise BadArgument("Get.fromData : Command body too long")
 	def fromStrReader(self,sr,cs):
 		"""Fill a Get Object from a StrReader
 		raise ParseError if it is malformed"""
@@ -311,9 +400,19 @@
 			self.l=sr.readMsgIdList(self,start,cs)
 		except (ParseError,IndexError):
 			raise ParseError("Bad Formed Command : Get")
-		
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=""
+		for i in range(len(self.l)):
+			s=s+self.l[i]
+		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+			raise BadArgument("Create.__str__ : command body too long")
+		return chr(5)+intToStrBE(len(s),3)+s
+	
 class Summarize(CommandCToS):
-	"""Summarize command"""
+	"""Summarize command
+	self.num : maximum number of synopsis to retrieve (int)
+	self.after : msgId older than the synopsese retrieved"""
 	def __init__(self):
 		"""Build a Summarize empty object"""
 		pass
@@ -325,6 +424,7 @@
 		if(len(m)!=msgIdLength): # or m is not a str
 			raise BadArgument(" Summarize.fromData : m is not a valid message ID")
 		self.after=m
+		#command body is small enough
 	def fromStrReader(self,sr,cs):
 		"""Fill a Summarize Object from a StrReader
 		raise ParseError if it is malformed"""
@@ -335,9 +435,16 @@
 			self.after=sr.next(msgIdLength)
 		except IndexError:
 			raise ParseError("Bad Formed Command : Summarize")
-		
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=intToStrBE(self.num,2)+self.after
+		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+			raise BadArgument("Summarize.__str__ : command body too long")
+		return chr(6)+intToStrBE(len(s),3)+s
+	
 class Delete(CommandCToS):
-	"""Delete command"""
+	"""Delete command
+	self.l : list of msgId (list of str of len msgIdLength)"""
 	def __init__(self):
 		"""Build a Delete empty object"""
 		pass
@@ -347,6 +454,8 @@
 		if( not isMsgIdList(li)):
 			raise BadArgument("Delete.fromData : li is not a list of message id")
 		self.l=li
+		if(msgIdLength*len(self.l)>256*256*256):
+			raise BadArgument("Delete.fromData : Command body too long")
 	def fromStrReader(self,sr,cs):
 		"""Fill a Delete Object from a StrReader
 		raise ParseError if it is malformed"""
@@ -355,18 +464,33 @@
 			self.l=sr.readMsgIdList(self,start,cs)
 		except (ParseError,IndexError):
 			raise ParseError("Bad Formed Command : Delete")
-		
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=""
+		for i in range(len(self.l)):
+			s=s+self.l[i]
+		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+			raise BadArgument("Create.__str__ : command body too long")
+		return chr(7)+intToStrBE(len(s),3)+s
+	
 class Policy(CommandCToS):
-	"""Policy command"""
+	"""Policy command
+	self.opt : option name (str)
+	self.val : option value (str)"""
 	def __init__(self):
 		"""Build a Policy empty object"""
 		pass
 	def fromData(self,opt,val):
 		"""Fill a Policy Object from 2 str : the option name and its value
 		It is the caller work to convert adequatly into a string the value he wants to be sent"""
-		#do we check the option names' validity?
+		#TODO check the option names' validity and the argument
+		#it's a lot of trouble -> later
+		#for the time being we suppose the developper knows what he does and does not create an message that will exceed the command body max size
+		if(len(opt)>255):
+			raise BadArgument("Policy.fromData : Option name length too big")
 		self.opt=opt
 		self.val=val
+		#command body is small enough
 	def fromStrReader(self,sr,cs):
 		"""Fill a Policy Object from a StrReader
 		raise ParseError if it is malformed"""
@@ -376,6 +500,12 @@
 			self.val=sr.next(cs-1-le)
 		except (IndexError,BadArgument):
 			raise ParseError("Bad Formed Command : Policy")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=chr(len(self.opt))+self.opt+self.val
+		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+			raise BadArgument("Policy.__str__ : command body too long")
+		return chr(8)+intToStrBE(len(s),3)+s
 		
 #empty class will be used as a framework fo CommandSToC classes
 class Frame(CommandCToS):

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2004-07-28 21:02:17 UTC (rev 37)
+++ trunk/TODO	2004-07-28 22:11:49 UTC (rev 38)
@@ -10,7 +10,7 @@
 
 
  - In case something brake, remember it's emag's fault.
- - add the __str__ method which outputs the message ready to be
+ o add the __str__ method which outputs the message ready to be
    sent(message.py)
  - add the print method which prints the content of a comand object in a user
    friendly form(message.py)