[Nym3-commit] r43 - trunk

nym3-devel@lists.noreply.org nym3-devel@lists.noreply.org
Fri, 30 Jul 2004 14:13:52 +0200


Author: jr
Date: 2004-07-30 14:13:50 +0200 (Fri, 30 Jul 2004)
New Revision: 43

Modified:
   trunk/Message.py
Log:
-added the CommandStoC parser
-rough testing


Modified: trunk/Message.py
===================================================================
--- trunk/Message.py	2004-07-28 23:10:41 UTC (rev 42)
+++ trunk/Message.py	2004-07-30 12:13:50 UTC (rev 43)
@@ -32,10 +32,10 @@
 			return aux(n/256,chr(n%256)+ac,mod-1)
 	return aux(n,"",mod)
 
-def isMidList(l):
-	"""true if l is a list of strings of length 20"""
+def isMidList(l,n):
+	"""true if l is a list of strings of length n"""
 	def isMid(e):
-		if( len(e)==20 and type(e)==types.StringType ):
+		if( len(e)==n and type(e)==types.StringType ):
 			return True
 		else:
 			return False
@@ -101,6 +101,30 @@
 			return a
 		except IndexError: #is it really necessary? is it not considered in the various fromStrReader ?
 			raise ParseError("Bad Formed Command")
+	def readCommandSToC(self):
+		"""Read next CommandSToC from string"""
+		try:
+			ct = ord(self.next(1))
+			cs = strToIntBE(self.next(3))
+			if (ct == 0):
+				a=Created()
+			elif (ct == 1):
+				a=Status()
+			elif (ct == 2):
+				a=Summary()
+			elif (ct == 3):
+				a=Msg()
+			elif (ct == 4):
+				a=Dropped()
+			elif (ct == 5):
+				a=Error()
+			else:
+				raise ParseError("Undefined Command Type")
+			a.fromStrReader(self,cs)
+			return a
+		except IndexError: #is it really necessary? is it not considered in the various fromStrReader ?
+			#it should, if not consider it a bug
+			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"""
@@ -118,19 +142,19 @@
 			return l
 		except ParseError: #is it really necessary?
 			raise
-	def readMid(self,start,cs):
-		"""Read a mid
-		Raise ParseError if it takes more characters from the string that previously advertised"""
-		if(self.b + midLength - start > cs):
+	def readMid(self,length,start,cs):
+		"""Read a str of len = length
+		Raise ParseError if it takes more characters from the string that previously advertised, in that case, doesn't read the StrReader"""
+		if(self.b + length - start > cs):
 			raise ParseError("Bad Formed Command")
-		return self.next(midLength)
-	def readMidList(self,start,cs):
-		"""Read a list of mid
+		return self.next(length)
+	def readMidList(self,length,start,cs):
+		"""Read a list of str of len length
 		Raise ParseError if it takes more characters from the string that previously advertised"""
 		try:
 			l = []
 			while(self.b < start + cs):
-				l.append(self.readMid(start,cs))
+				l.append(self.readMid(length,start,cs))
 			return l
 		except ParseError: #is it really necessary?
 			raise
@@ -237,11 +261,11 @@
 		"""Fill a Create command from a StrReader
 		raise ParseError if it is malformed"""
 		start=sr.b
-		nNym = ord(sr.next(1))
-		self.pw = "" #what is a proof of work?
 		try:
+			nNym = ord(sr.next(1))
+			self.pw = "" #what is a proof of work?
 			self.list = sr.readNymList(start,cs)
-		except ParseError:
+		except (ParseError,IndexError):
 			raise ParseError("Bad Formed Command : Create")
 		#nNym is redundant, we use it to make sure the message is well formed
 		if(nNym != len(self.list)):
@@ -251,7 +275,7 @@
 		s=chr(len(self.list))+self.pw
 		for i in range(len(self.list)):
 			s=s+chr(len(self.list[i]))+self.list[i]
-		if(len(s)>(256*256*256)): #should not be possible, otherwise, bug
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise, bug
 			raise BadArgument("Create.__str__ : command body too long")
 		return chr(0)+intToStrBE(len(s),3)+s
 		
@@ -270,11 +294,14 @@
 	def fromStrReader(self,sr,cs):
 		"""Fill a Create2 command from a StrReader
 		raise ParseError if it is malformed"""
-		self.cr=sr.next(cs)
+		try:
+			self.cr=sr.next(cs)
+		except IndexError:
+			raise ParseError("Bad Formed Command : Create2")
 	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
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
 			raise BadArgument("Create2.__str__ : command body too long")
 		return chr(1)+intToStrBE(len(s),3)+s
 	
@@ -287,18 +314,21 @@
 	def fromData(self,s):
 		"""Fill a Surb Object from a string containing Surbs"""
 		self.surbs=s
-		if(len(s)>(256*256*256)):
+		if(len(s)>=pow(256,3)):
 			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)
+		try:
+			self.surbs=sr.next(cs)
+		except IndexError:
+			raise ParseError("Bad Formed Command : Surb")
 	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
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
 			raise BadArgument("Surb.__str__ : command body too long")
 		return chr(2)+intToStrBE(len(s),3)+s
 	
@@ -336,7 +366,7 @@
 		"""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
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
 			raise BadArgument("Newpk.__str__ : command body too long")
 		return chr(3)+intToStrBE(len(s),3)+s
 	
@@ -355,11 +385,11 @@
 			raise BadArgument("Relay.fromData : RT size isn't 2 bytes")
 		self.rt=rt
 		self.rs=len(ri)
-		if(self.rs > 256*256):
+		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)):
+		if(4+self.rs+len(body) >= pow(256,3)):
 			raise BadArgument("Relay.fromData : Command body too long")
 	def fromStrReader(self,sr,cs):
 		"""Fill a Relay Object from a StrReader
@@ -374,7 +404,7 @@
 	def __str__(self):
 		"""Give the string of the Command that would be sent in a control message"""
 		s=intToStrBE(self.rs,2)+self.rt+self.ri+self.body
-		if(len(s)>(256*256*256)): #should not be possible, otherwise bug
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
 			raise BadArgument("Relay.__str__ : Command Body too long")
 		return chr(4)+intToStrBE(len(s),3)+s
 	
@@ -387,17 +417,17 @@
 	def fromData(self,li):
 		"""Fill a Get Object from a list of message id (=string of len 20)"""
 		#check that each element of the list has 20 bytes
-		if( not isMidList(li)):
+		if( not isMidList(li,midLength)):
 			raise BadArgument("Get.fromData : li is not a list of message id")
 		self.l=li
-		if(midLength*len(self.l)>256*256*256):
+		if(midLength*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"""
 		start=sr.b
 		try:
-			self.l=sr.readMidList(start,cs)
+			self.l=sr.readMidList(midLength,start,cs)
 		except (ParseError,IndexError):
 			raise ParseError("Bad Formed Command : Get")
 	def __str__(self):
@@ -405,7 +435,7 @@
 		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
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
 			raise BadArgument("Get.__str__ : command body too long")
 		return chr(5)+intToStrBE(len(s),3)+s
 	
@@ -438,7 +468,7 @@
 	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
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
 			raise BadArgument("Summarize.__str__ : command body too long")
 		return chr(6)+intToStrBE(len(s),3)+s
 	
@@ -451,17 +481,17 @@
 	def fromData(self,li):
 		"""Fill a Delete Object from a list of message ID (string of length midLength"""
 		#check that each element of the list has 20 bytes
-		if( not isMidList(li)):
+		if( not isMidList(li,midLength)):
 			raise BadArgument("Delete.fromData : li is not a list of message id")
+		if(midLength*len(li)>=pow(256,3)):
+			raise BadArgument("Delete.fromData : Command body too long")
 		self.l=li
-		if(midLength*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"""
 		start=sr.b
 		try:
-			self.l=sr.readMidList(start,cs)
+			self.l=sr.readMidList(midLength,start,cs)
 		except (ParseError,IndexError):
 			raise ParseError("Bad Formed Command : Delete")
 	def __str__(self):
@@ -469,7 +499,7 @@
 		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
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
 			raise BadArgument("Delete.__str__ : command body too long")
 		return chr(7)+intToStrBE(len(s),3)+s
 	
@@ -503,23 +533,228 @@
 	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
+		if(len(s)>=pow(256,3)): #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):
-	"""command"""
+	
+class CommandSToC:
+	"""CommandSToC astract class
+	the CommandSToC derive from this class"""
+	pass
+
+class Created(CommandSToC):
+	"""command Created
+	self.nym : nym of the created account (str)
+	self.challenge : challenge (str)"""
 	def __init__(self):
-		"""Build a empty object"""
+		"""Build a empty Created object"""
 		pass
-	def fromData(self,):
-		"""Fill a Object from """
+	def fromData(self,nym,ch):
+		"""Fill a Created Object from a nym(str) and a challenge(str) """
+		if(len(nym)>255):
+			raise BadArgument("Created.fromData : nym too long")
+		if(1+len(nym)+len(ch) >= pow(256,3)):
+			raise BadArgument("Created.fromData : challenge too long")
+		self.nym=nym
+		self.challenge=ch
 	def fromStrReader(self,sr,cs):
+		"""Fill a Created Object from a StrReader
+		raise ParseError if it is malformed"""
+		start=sr.b
+		try:
+			self.nym=sr.readNym(start,cs)
+			self.challenge=sr.next(cs+start-sr.b)
+		except (IndexError,ParseError,BadArgument):
+			raise ParseError("Bad Formed Command : Created")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=chr(len(self.nym))+self.nym+self.challenge
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
+			raise BadArgument("Created.__str__ : command body too long")
+		return chr(0)+intToStrBE(len(s),3)+s
+
+class Status(CommandSToC):
+	"""command Status
+	self.nMsg : number of email waiting (int)
+	self.nSurb : number of surbs left (int)
+	self.quota : maximum storage on nymserver in byte (int)
+	self.used : used storage in byte (int)
+	self.acks : list of seqno (list of (str of length seqNoLength))"""
+	def __init__(self):
+		"""Build a empty Status object"""
+		pass
+	def fromData(self,nM,nS,q,u,l):
+		"""Fill a Status Object from a number of message(int), a number of surbs(int), a quota(int), a used(int) and a sequence of seqno(list of (str of size seqNoLength)"""
+		#TODO replace the error by the taking of the maximal value?
+		if(nM>=pow(256,4)):
+			raise BadArgument("Status.fromData : number of waiting e-mail too large")
+		if(nM>=pow(256,2)):
+			raise BadArgument("Status.fromData : number of available surbs too large")
+		if(q>=pow(256,4)):
+			raise BadArgument("Status.fromData : quota too large")
+		if(u>=pow(256,4)):
+			raise BadArgument("Status.fromData : used space too large")
+		if(not isMidList(l,seqNoLength)):
+			raise BadArgument("Status.fromData : l is not a list of Sequence Number")
+		if(14+seqNoLength*len(l)>=pow(256,3)):
+			raise BadArgument("Status.fromData : l is too long")
+		self.nMsg=nM
+		self.nSurb=nS
+		self.quota=q
+		self.used=u
+		self.acks=l
+	def fromStrReader(self,sr,cs):
+		"""Fill a Status Object from a StrReader
+		raise ParseError if it is malformed"""
+		try:
+			start=sr.b
+			self.nMsg=strToIntBE(sr.next(4))
+			self.nSurb=strToIntBE(sr.next(2))
+			self.quota=strToIntBE(sr.next(4))
+			self.used=strToIntBE(sr.next(4))
+			self.acks=sr.readMidList(seqNoLength,start,cs)
+		except (IndexError,ParseError):
+			raise ParseError("Bad Formed Command : Status")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=intToStrBE(self.nMsg,4)+intToStrBE(self.nSurb,2)+intToStrBE(self.quota,4)+intToStrBE(self.used,4)
+		for i in range(len(self.acks)):
+			s=s+self.acks[i]
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
+			raise BadArgument("Status.__str__ : command body too long")
+		return chr(1)+intToStrBE(len(s),3)+s
+
+class Summary(CommandSToC):
+	"""command Summary
+	self.bf : bit field indicating which one of the synopsis as a mail
+	self.synSet : Encrypted synopses set
+	"""
+	def __init__(self):
+		"""Build a empty Summary object"""
+		pass
+	def fromData(self,bf,ess):
+		"""Fill a Object from bit field (str of len 2) and an encrypted set of synopses(str)"""
+		if(len(bf)!=2):
+			raise BadArgument("Summary.fromData : bit field has not the good size, and size DOES matter")
+		if(2+len(ess)>=pow(256,3)):
+			raise BadArgument("Summary.fromData : Encrypted set of synopses too long")
+		self.bf=bf
+		self.synSet=ess
+	def fromStrReader(self,sr,cs):
 		"""Fill a Object from a StrReader
 		raise ParseError if it is malformed"""
+		try:
+			self.bf=sr.next(2)
+			self.synSet=sr.next(cs-2)
+		except IndexError:
+			ParseError("Bad Formed Command : Summary")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=self.bf+self.synSet
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
+			raise BadArgument("Summary.__str__ : command body too long")
+		return chr(2)+intToStrBE(len(s),3)+s
 
+class Msg(CommandSToC):
+	"""command Msg
+	self.mid : message ID (str of length midLength)
+	self.msg : encrypted email (str)
+	"""
+	def __init__(self):
+		"""Build a empty Msg object"""
+		pass
+	def fromData(self,mid,msg):
+		"""Fill a Msg Object from a Mid (str onf length midLength) and an encrypted msg (str)"""
+		if(len(mid) != midLength):
+			raise BadArgument("Msg.fromData : mid has not the good length")
+		if(midLength + len(msg) >= pow(256,3)):
+			raise BadArgument("Msg.fromData : msg too long")
+		self.mid=mid
+		self.msg=msg
+	def fromStrReader(self,sr,cs):
+		"""Fill a Msg Object from a StrReader
+		raise ParseError if it is malformed"""
+		try:
+			start=sr.b
+			self.mid=sr.readMid(midLength,start,cs)
+			self.msg=sr.next(cs-midLength)
+		except (IndexError,ParseError):
+			raise ParseError("Bad Formed Command : Msg")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=self.mid+self.msg
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
+			raise BadArgument("Msg.__str__ : command body too long")
+		return chr(3)+intToStrBE(len(s),3)+s
 
+class Dropped(CommandSToC):
+	"""command Dropped
+	self.list : list of mid (list of (str of size midLength))
+	"""
+	def __init__(self):
+		"""Build a empty Dropped object"""
+		pass
+	def fromData(self,l):
+		"""Fill a Dropped Object from a list of mid"""
+		if( not isMidList(l,midLength)):
+			raise BadArgument("Dropped.fromData : l is not a list of message id")
+		if(midLength*len(l)>=pow(256,3)):
+			raise BadArgument("Dropped.fromData : Command body too long")
+		self.list=l
+	def fromStrReader(self,sr,cs):
+		"""Fill a Dropped Object from a StrReader
+		raise ParseError if it is malformed"""
+		start=sr.b
+		try:
+			self.list=sr.readMidList(midLength,start,cs)
+		except (ParseError,IndexError):
+			raise ParseError("Bad Formed Command : Dropped")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=""
+		for i in range(len(self.list)):
+			s=s+self.list[i]
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
+			raise BadArgument("DroppedCreated.__str__ : command body too long")
+		return chr(4)+intToStrBE(len(s),3)+s
+
+class Error(CommandSToC):
+	"""command Error
+	self.nonce : nonce from client message (str of size seqNo)
+	self.error : english langage error description (str)
+	"""
+	def __init__(self):
+		"""Build a empty Error object"""
+		pass
+	def fromData(self,seqNo,error):
+		"""Fill a Object from a seqno (str of len seqNoLength) and an error message(str)"""
+		if(len(seqNo) != seqNoLength):
+			raise BadArgument("Error.fromData : seqNo has not the good length")
+		if(seqNoLength + len(error) >= pow(256,3)):
+			raise BadArgument("Error.fromData : msg too long")
+		self.nonce=seqNo
+		self.error=error
+	def fromStrReader(self,sr,cs):
+		"""Fill a Object from a StrReader
+		raise ParseError if it is malformed"""
+		try:
+			start=sr.b
+			self.mid=sr.readMid(seqNoLength,start,cs)
+			self.msg=sr.next(cs-seqNoLength)
+		except (IndexError,ParseError):
+			raise ParseError("Bad Formed Command : Error")
+	def __str__(self):
+		"""Give the string of the Command that would be sent in a control message"""
+		s=self.nonce+self.error
+		if(len(s)>=pow(256,3)): #should not be possible, otherwise bug
+			raise BadArgument("Error.__str__ : command body too long")
+		return chr(5)+intToStrBE(len(s),3)+s
+
+
+
+
+
 if (__name__ == '__main__'):
 	import Mail
 	l=[]
@@ -628,3 +863,75 @@
 	del(C)
 	del(D)
 	del(S)
+
+	print "test Created"
+	C=Created()
+	C.fromData("Marsux","what is the answer to universe life and everything")
+	s1=C.__str__()
+	S=StrReader(s1)
+	D=S.readCommandSToC()
+	s2=D.__str__()
+	print (s1==s2)
+	del(C)
+	del(D)
+	del(S)
+
+	print "test Status"
+	C=Status()
+	C.fromData(5,10,424242,212121,l)
+	s1=C.__str__()
+	S=StrReader(s1)
+	D=S.readCommandSToC()
+	s2=D.__str__()
+	print (s1==s2)
+	del(C)
+	del(D)
+	del(S)
+
+	print "test Summary"
+	C=Summary()
+	C.fromData("ab","this should be an encrypted set of synopses")
+	s1=C.__str__()
+	S=StrReader(s1)
+	D=S.readCommandSToC()
+	s2=D.__str__()
+	print (s1==s2)
+	del(C)
+	del(D)
+	del(S)
+
+	print "test Msg"
+	C=Msg()
+	C.fromData(l[0],"Say something stupid, like, I am wearing female's underwear")
+	s1=C.__str__()
+	S=StrReader(s1)
+	D=S.readCommandSToC()
+	s2=D.__str__()
+	print (s1==s2)
+	del(C)
+	del(D)
+	del(S)
+
+	print "test Dropped"
+	C=Dropped()
+	C.fromData(l)
+	s1=C.__str__()
+	S=StrReader(s1)
+	D=S.readCommandSToC()
+	s2=D.__str__()
+	print (s1==s2)
+	del(C)
+	del(D)
+	del(S)
+
+	print "test Error"
+	C=Msg()
+	C.fromData(l[0],"I am being repressed")
+	s1=C.__str__()
+	S=StrReader(s1)
+	D=S.readCommandSToC()
+	s2=D.__str__()
+	print (s1==s2)
+	del(C)
+	del(D)
+	del(S)