~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/testament.py

  • Committer: Lukáš Lalinský
  • Date: 2008-08-17 19:31:03 UTC
  • mto: (3650.1.1 bzr.ab.integration)
  • mto: This revision was merged to the branch mainline in revision 3651.
  • Revision ID: lalinsky@gmail.com-20080817193103-nph9o92j2177iq96
Handle references to line data in _patiencediff_c.c properly

This code is called in bzrlib only with lists or tuples of strings, which works fine, because PySequence_Fast always returns the same object and so the items from PySequence_Fast_GET_ITEM will not be deleted until the original sequence is deleted. But if it's called with a sequence than needs to be converted to list (e.g. PyUnicode), the items will be garbage collected in the contructor and still used later in code (which leads to segfaults).

Show diffs side-by-side

added added

removed removed

Lines of Context:
106
106
        self.parent_ids = rev.parent_ids[:]
107
107
        self.inventory = inventory
108
108
        self.revprops = copy(rev.properties)
109
 
        assert not contains_whitespace(self.revision_id)
110
 
        assert not contains_linebreaks(self.committer)
 
109
        if contains_whitespace(self.revision_id):
 
110
            raise ValueError(self.revision_id)
 
111
        if contains_linebreaks(self.committer):
 
112
            raise ValueError(self.committer)
111
113
 
112
114
    def as_text_lines(self):
113
115
        """Yield text form as a sequence of lines.
125
127
        # inventory length contains the root, which is not shown here
126
128
        a('parents:\n')
127
129
        for parent_id in sorted(self.parent_ids):
128
 
            assert not contains_whitespace(parent_id)
 
130
            if contains_whitespace(parent_id):
 
131
                raise ValueError(parent_id)
129
132
            a('  %s\n' % parent_id)
130
133
        a('message:\n')
131
134
        for l in self.message.splitlines():
134
137
        for path, ie in self._get_entries():
135
138
            a(self._entry_to_line(path, ie))
136
139
        r.extend(self._revprops_to_lines())
137
 
        if __debug__:
138
 
            for l in r:
139
 
                assert isinstance(l, basestring), \
140
 
                    '%r of type %s is not a plain string' % (l, type(l))
141
140
        return [line.encode('utf-8') for line in r]
142
141
 
143
142
    def _get_entries(self):
146
145
        return entries
147
146
 
148
147
    def _escape_path(self, path):
149
 
        assert not contains_linebreaks(path)
 
148
        if contains_linebreaks(path):
 
149
            raise ValueError(path)
150
150
        return unicode(path.replace('\\', '/').replace(' ', '\ '))
151
151
 
152
152
    def _entry_to_line(self, path, ie):
153
153
        """Turn an inventory entry into a testament line"""
154
 
        assert not contains_whitespace(ie.file_id)
155
 
 
 
154
        if contains_whitespace(ie.file_id):
 
155
            raise ValueError(ie.file_id)
156
156
        content = ''
157
157
        content_spacer=''
158
158
        if ie.kind == 'file':
159
159
            # TODO: avoid switching on kind
160
 
            assert ie.text_sha1
 
160
            if not ie.text_sha1:
 
161
                raise AssertionError()
161
162
            content = ie.text_sha1
162
163
            content_spacer = ' '
163
164
        elif ie.kind == 'symlink':
164
 
            assert ie.symlink_target
 
165
            if not ie.symlink_target:
 
166
                raise AssertionError()
165
167
            content = self._escape_path(ie.symlink_target)
166
168
            content_spacer = ' '
167
169
 
186
188
            return []
187
189
        r = ['properties:\n']
188
190
        for name, value in sorted(self.revprops.items()):
189
 
            assert isinstance(name, str)
190
 
            assert not contains_whitespace(name)
 
191
            if contains_whitespace(name):
 
192
                raise ValueError(name)
191
193
            r.append('  %s:\n' % name)
192
194
            for line in value.splitlines():
193
195
                r.append(u'    %s\n' % line)
223
225
        return self.inventory.iter_entries()
224
226
 
225
227
    def _escape_path(self, path):
226
 
        assert not contains_linebreaks(path)
 
228
        if contains_linebreaks(path):
 
229
            raise ValueError(path)
227
230
        if path == '':
228
231
            path = '.'
229
232
        return unicode(path.replace('\\', '/').replace(' ', '\ '))