comparison mercurial/revlog.py @ 42807:90f5dfc9c42a

revlog: avoid caching raw text too early in _revisiondata Without this change, we could cache the rawtext without considering for it validating the cache or not. If the exception raised by the invalid hash were to be caught and the same revision accessed again, the invalid rawtext would be returned.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Mon, 19 Aug 2019 16:29:43 +0200
parents 616aa62e5027
children e91411fcc697
comparison
equal deleted inserted replaced
42806:616aa62e5027 42807:90f5dfc9c42a
1631 # The text as stored inside the revlog. Might be the revision or might 1631 # The text as stored inside the revlog. Might be the revision or might
1632 # need to be processed to retrieve the revision. 1632 # need to be processed to retrieve the revision.
1633 rawtext = None 1633 rawtext = None
1634 # An intermediate text to apply deltas to 1634 # An intermediate text to apply deltas to
1635 basetext = None 1635 basetext = None
1636 # Do we need to update the rawtext cache once it is validated ?
1637 needcaching = True
1636 1638
1637 # Check if we have the entry in cache 1639 # Check if we have the entry in cache
1638 # The cache entry looks like (node, rev, rawtext) 1640 # The cache entry looks like (node, rev, rawtext)
1639 if self._revisioncache: 1641 if self._revisioncache:
1640 if self._revisioncache[0] == node: 1642 if self._revisioncache[0] == node:
1643 needcaching = False
1641 # _cache only stores rawtext 1644 # _cache only stores rawtext
1642 # rawtext is reusable. but we might need to run flag processors 1645 # rawtext is reusable. but we might need to run flag processors
1643 rawtext = self._revisioncache[2] 1646 rawtext = self._revisioncache[2]
1644 if raw: 1647 if raw:
1645 # if we don't want to process the raw text and that raw 1648 # if we don't want to process the raw text and that raw
1678 basetext = bytes(bins[0]) 1681 basetext = bytes(bins[0])
1679 bins = bins[1:] 1682 bins = bins[1:]
1680 1683
1681 rawtext = mdiff.patches(basetext, bins) 1684 rawtext = mdiff.patches(basetext, bins)
1682 del basetext # let us have a chance to free memory early 1685 del basetext # let us have a chance to free memory early
1683 self._revisioncache = (node, rev, rawtext)
1684 1686
1685 if flags is None: 1687 if flags is None:
1686 if rev is None: 1688 if rev is None:
1687 rev = self.rev(node) 1689 rev = self.rev(node)
1688 flags = self.flags(rev) 1690 flags = self.flags(rev)
1689 1691
1690 text, validatehash = self._processflags(rawtext, flags, 'read', raw=raw) 1692 text, validatehash = self._processflags(rawtext, flags, 'read', raw=raw)
1691 if validatehash: 1693 if validatehash:
1692 self.checkhash(text, node, rev=rev) 1694 self.checkhash(text, node, rev=rev)
1695
1696 if needcaching:
1697 self._revisioncache = (node, rev, rawtext)
1693 1698
1694 return text 1699 return text
1695 1700
1696 def rawdata(self, nodeorrev, _df=None): 1701 def rawdata(self, nodeorrev, _df=None):
1697 """return an uncompressed raw data of a given node or revision number. 1702 """return an uncompressed raw data of a given node or revision number.