~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/_knit_load_data_c.pyx

  • Committer: John Arbash Meinel
  • Date: 2007-06-29 16:00:06 UTC
  • mto: This revision was merged to the branch mainline in revision 2614.
  • Revision ID: john@arbash-meinel.com-20070629160006-sdhws6bdttdbgua8
Test that we properly verify the size and position strings.

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
    void *memchr(void *s, int c, size_t n)
61
61
 
62
62
 
 
63
cdef int string_to_int_safe(char *s, char *end, int *out) except -1:
 
64
    """Convert a base10 string to an integer.
 
65
 
 
66
    This makes sure the whole string is consumed, or it raises ValueError.
 
67
    This is similar to how int(s) works, except you don't need a Python
 
68
    String object.
 
69
 
 
70
    :param s: The string to convert
 
71
    :param end: The character after the integer. So if the string is '12\0',
 
72
        this should be pointing at the '\0'. If the string was '12 ' then this
 
73
        should point at the ' '.
 
74
    :param out: This is the integer that will be returned
 
75
    :return: -1 if an exception is raised. 0 otherwise
 
76
    """
 
77
    cdef char *integer_end
 
78
 
 
79
    # We can't just return the integer because of how pyrex determines when
 
80
    # there is an exception.
 
81
    out[0] = strtol(s, &integer_end, 10)
 
82
    if integer_end != end:
 
83
        py_s = PyString_FromStringAndSize(s, end-s)
 
84
        raise ValueError('%r is not a valid integer' % (py_s,))
 
85
    return 0
 
86
 
 
87
 
63
88
cdef class KnitIndexReader:
64
89
 
65
90
    cdef object kndx
149
174
                                                    next - parent_str)
150
175
            else:
151
176
                # This in an integer mapping to original
152
 
                # TODO: ensure that we are actually parsing the string
153
 
                int_parent = strtol(parent_str, &parent_end, 10)
 
177
                string_to_int_safe(parent_str, next, &int_parent)
154
178
 
155
 
                # Can the parent be decoded to get its parent row? This
156
 
                # at a minimum will cause this row to have wrong parents, or
157
 
                # even to apply a delta to the wrong base and decode
158
 
                # incorrectly. its therefore not usable, and because we have
159
 
                # encountered a situation where a new knit index had this
160
 
                # corrupt we can't asssume that no other rows referring to the
161
 
                # index of this record actually mean the subsequent uncorrupt
162
 
                # one, so we error.
163
179
                if int_parent >= self.history_len:
164
180
                    raise IndexError('Parent index refers to a revision which'
165
181
                        ' does not exist yet.'
166
182
                        ' %d > %d' % (int_parent, self.history_len))
167
 
                if parent_end < next:
168
 
                    # We didn't process all of the string, which means it isn't
169
 
                    # a complete integer.
170
 
                    py_parent = PyString_FromStringAndSize(parent_str,
171
 
                                                           next - parent_str)
172
 
                    raise ValueError('%r is not a valid integer' % (py_parent,))
173
183
                parent = PyList_GET_ITEM(self.history, int_parent)
174
184
                # PyList_GET_ITEM steals a reference
175
185
                Py_INCREF(parent)
213
223
            return 0
214
224
        size_str = size_str + 1
215
225
 
216
 
        # TODO: Make sure this works when there are no parents
217
226
        parent_str = <char*>memchr(size_str, c' ', end - size_str)
218
227
        if parent_str == NULL or parent_str >= end:
219
228
            # Missing parents
224
233
                                                version_id_size)
225
234
        options = self.process_options(option_str, option_end)
226
235
 
227
 
        # TODO: Check that we are actually reading integers
228
 
        pos = strtol(pos_str, NULL, 10)
229
 
        size = strtol(size_str, NULL, 10)
230
 
 
231
236
        try:
 
237
            string_to_int_safe(pos_str, size_str - 1, &pos)
 
238
            string_to_int_safe(size_str, parent_str - 1, &size)
232
239
            parents = self.process_parents(parent_str, end)
233
240
        except (ValueError, IndexError), e:
234
241
            py_line = PyString_FromStringAndSize(start, end - start)