
Python Homework Solution on Fixing your Security Layer
- 23rd Dec, 2021
- 00:27 AM
TYPE="type" ARGS="args" RETURN="return" EXCP="exceptions" TARGET="target" FUNC="func" OBJC="objc" class ABFile(): def __init__(self,filename,create): # globals mycontext['debug'] = False # local (per object) reference to the underlying file self.Afn = filename+'.a' self.Bfn = filename+'.b' #Create A/B Files if create: #Checks if Backup File already present, else Creates A/B Files and writes "SE" to A if self.Afn in listfiles(): #Backup File Present, open A/B File -> Original A File, Empty B File self.Afile = openfile(self.Afn,create) self.Bfile = openfile(self.Bfn,create) self.Bfile.writeat(self.Afile.readat(None,0),0) else: self.Afile = openfile(self.Afn,create) self.Bfile = openfile(self.Bfn,create) self.Afile.writeat('SE', 0) else: #Check if Backup File Present, else raise an Exception if self.Afn in listfiles(): self.Afile = openfile(self.Afn,True) self.Bfile = openfile(self.Bfn,True) self.Bfile.writeat(self.Afile.readat(None,0),0) else: raise FileNotFoundError #WriteAt Function - Lock, Offset and Length Validation then Write the Data #For Write Call, Lock provides better handling of multiple writes to a file def writeat(self,data,offset): #Creating the Lock self.lock = createlock() #Set the Lock to Blocking self.lock.acquire(True) #Offset Validation for Write Call if offset < 0: raise RepyArgumentError self.lock.release() elif offset > len(self.Bfile.readat(None,0)): raise SeekPastEndOfFileError self.lock.release() else: #After Correct Validation -> Write to File and Release Lock self.Bfile.writeat(data,offset) self.lock.release() #ReadAt Function - Offset and Length Validation then Read & Return ReadData def readat(self,bytes,offset): #Creating the Lock self.lock = createlock() #Set the Lock to Blocking self.lock.acquire(True) #Offset and Length Validation for Read Call length = len(self.Afile.readat(None,0)) if offset < 0 or length < 0: raise RepyArgumentError self.lock.release() elif offset >= len(self.Afile.readat(None,0)): raise SeekPastEndOfFileError self.lock.release() elif bytes > length and bytes != None: raise SeekPastEndOfFileError self.lock.release() elif (len(self.Afile.readat(None,0)) < offset+length) and bytes != None: raise RepyArgumentError self.lock.release() else: #Try Reading the File else raise Exception try: read_data = self.Afile.readat(bytes,offset) self.lock.release() return read_data except: raise RepyArgumentError #Close Function Call - If both files are valid, older one is discarded else invalid file is discarded def close(self): #Data stored in variables for restoration of data backup_data = self.Afile.readat(None,0) data = self.Bfile.readat(None,0) backupfile = self.Afn #Check if the written file starts with "S" and ends with "E" if self.Bfile.readat(None,0).startswith("S") and self.Bfile.readat(None,0).endswith("E"): #The Written File is Valid -> Discard Older Version self.Afile.close() self.Bfile.close() removefile(self.Afn) openfile(backupfile,True).writeat(data,0) removefile(self.Bfn) else: #The Written File is Invalid -> Discard Invalid File self.Afile.close() self.Bfile.close() removefile(self.Afn) openfile(backupfile,True).writeat(backup_data,0) removefile(self.Bfn) #Opens A/B Files if exist, else gives an Exception -> File Not Found def ABopenfile(filename, create): return ABFile(filename,create) # The code here sets up type checking and variable hiding for you. You # should not need to change anything below here. sec_file_def = {"obj-type":ABFile, "name":"ABFile", "writeat":{"type":"func","args":(str,(int,long)),"exceptions":Exception,"return":(int,type(None)),"target":ABFile.writeat}, "readat":{"type":"func","args":((int,long,type(None)),(int,long)),"exceptions":Exception,"return":str,"target":ABFile.readat}, "close":{"type":"func","args":None,"exceptions":None,"return":(bool,type(None)),"target":ABFile.close} } CHILD_CONTEXT_DEF["ABopenfile"] = {TYPE:OBJC,ARGS:(str,bool),EXCP:Exception,RETURN:sec_file_def,TARGET:ABopenfile} # Execute the user code secure_dispatch_module()