comparison mercurial/patch.py @ 16524:ed6a74312176 stable

patch: be more tolerant with EOLs in binary diffs (issue2870) The only place where an trailing CR could be meaningful is in the "diff --git" line as part of a filename, and existing code already rule out this possibility. Extend the CR/LF filtering to the whole binary hunk.
author Patrick Mezard <patrick@mezard.eu>
date Thu, 26 Apr 2012 21:44:02 +0200
parents 727068417b95
children aef3d0d4631c fcb97d9a26cd
comparison
equal deleted inserted replaced
16523:727068417b95 16524:ed6a74312176
1033 1033
1034 def new(self): 1034 def new(self):
1035 return [self.text] 1035 return [self.text]
1036 1036
1037 def _read(self, lr): 1037 def _read(self, lr):
1038 line = lr.readline() 1038 def getline(lr, hunk):
1039 self.hunk.append(line) 1039 l = lr.readline()
1040 hunk.append(l)
1041 return l.rstrip('\r\n')
1042
1043 line = getline(lr, self.hunk)
1040 while line and not line.startswith('literal '): 1044 while line and not line.startswith('literal '):
1041 line = lr.readline() 1045 line = getline(lr, self.hunk)
1042 self.hunk.append(line)
1043 if not line: 1046 if not line:
1044 raise PatchError(_('could not extract "%s" binary data') 1047 raise PatchError(_('could not extract "%s" binary data')
1045 % self._fname) 1048 % self._fname)
1046 size = int(line[8:].rstrip()) 1049 size = int(line[8:].rstrip())
1047 dec = [] 1050 dec = []
1048 line = lr.readline() 1051 line = getline(lr, self.hunk)
1049 self.hunk.append(line)
1050 while len(line) > 1: 1052 while len(line) > 1:
1051 l = line[0] 1053 l = line[0]
1052 if l <= 'Z' and l >= 'A': 1054 if l <= 'Z' and l >= 'A':
1053 l = ord(l) - ord('A') + 1 1055 l = ord(l) - ord('A') + 1
1054 else: 1056 else:
1055 l = ord(l) - ord('a') + 27 1057 l = ord(l) - ord('a') + 27
1056 try: 1058 try:
1057 dec.append(base85.b85decode(line[1:-1])[:l]) 1059 dec.append(base85.b85decode(line[1:])[:l])
1058 except ValueError, e: 1060 except ValueError, e:
1059 raise PatchError(_('could not decode "%s" binary patch: %s') 1061 raise PatchError(_('could not decode "%s" binary patch: %s')
1060 % (self._fname, str(e))) 1062 % (self._fname, str(e)))
1061 line = lr.readline() 1063 line = getline(lr, self.hunk)
1062 self.hunk.append(line)
1063 text = zlib.decompress(''.join(dec)) 1064 text = zlib.decompress(''.join(dec))
1064 if len(text) != size: 1065 if len(text) != size:
1065 raise PatchError(_('"%s" length is %d bytes, should be %d') 1066 raise PatchError(_('"%s" length is %d bytes, should be %d')
1066 % (self._fname, len(text), size)) 1067 % (self._fname, len(text), size))
1067 self.text = text 1068 self.text = text
1211 if emitfile: 1212 if emitfile:
1212 emitfile = False 1213 emitfile = False
1213 yield 'file', (afile, bfile, h, gp and gp.copy() or None) 1214 yield 'file', (afile, bfile, h, gp and gp.copy() or None)
1214 yield 'hunk', h 1215 yield 'hunk', h
1215 elif x.startswith('diff --git'): 1216 elif x.startswith('diff --git'):
1216 m = gitre.match(x) 1217 m = gitre.match(x.rstrip(' \r\n'))
1217 if not m: 1218 if not m:
1218 continue 1219 continue
1219 if gitpatches is None: 1220 if gitpatches is None:
1220 # scan whole input for git metadata 1221 # scan whole input for git metadata
1221 gitpatches = scangitpatch(lr, x) 1222 gitpatches = scangitpatch(lr, x)