Merge lp:~wiml/libdrizzle/integer-sizes into lp:libdrizzle
- integer-sizes
- Merge into libdrizzle-redux
Proposed by
Wim Lewis
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Approved by: | Andrew Hutchings | ||||||||
Approved revision: | 121 | ||||||||
Merged at revision: | 109 | ||||||||
Proposed branch: | lp:~wiml/libdrizzle/integer-sizes | ||||||||
Merge into: | lp:libdrizzle | ||||||||
Diff against target: |
618 lines (+134/-80) 14 files modified
libdrizzle-5.1/constants.h (+15/-21) libdrizzle-5.1/field_client.h (+17/-2) libdrizzle/binlog.cc (+5/-5) libdrizzle/conn.cc (+6/-0) libdrizzle/field.cc (+36/-18) libdrizzle/handshake.cc (+2/-2) libdrizzle/pack.cc (+19/-7) libdrizzle/pack.h (+2/-1) libdrizzle/result.cc (+10/-8) libdrizzle/result.h (+6/-6) libdrizzle/statement.cc (+1/-1) libdrizzle/statement_param.cc (+8/-2) libdrizzle/structs.h (+6/-6) tests/unit/statement.c (+1/-1) |
||||||||
To merge this branch: | bzr merge lp:~wiml/libdrizzle/integer-sizes | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Andrew Hutchings | Approve | ||
Review via email: mp+152963@code.launchpad.net |
Commit message
Adjusting the sizes of integer variables to avoid truncation or overflow; also fixed some errors reading large responses or prepared-statement responses.
Description of the change
This is the result of examining libdrizzle for integer truncation and overflow problems. A few other small bugs were found and fixed along the way--- see the individual commit messages for these.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'libdrizzle-5.1/constants.h' |
2 | --- libdrizzle-5.1/constants.h 2013-01-28 01:04:53 +0000 |
3 | +++ libdrizzle-5.1/constants.h 2013-03-12 16:48:27 +0000 |
4 | @@ -604,27 +604,21 @@ |
5 | */ |
6 | |
7 | /* Protocol unpacking macros. */ |
8 | -#define drizzle_get_byte2(__buffer) \ |
9 | - (uint16_t)((__buffer)[0] | \ |
10 | - ((__buffer)[1] << 8)) |
11 | -#define drizzle_get_byte3(__buffer) \ |
12 | - (uint32_t)((__buffer)[0] | \ |
13 | - ((__buffer)[1] << 8) | \ |
14 | - ((__buffer)[2] << 16)) |
15 | -#define drizzle_get_byte4(__buffer) \ |
16 | - (uint32_t)((__buffer)[0] | \ |
17 | - ((__buffer)[1] << 8) | \ |
18 | - ((__buffer)[2] << 16) | \ |
19 | - ((__buffer)[3] << 24)) |
20 | -#define drizzle_get_byte8(__buffer) \ |
21 | - ((uint64_t)(__buffer)[0] | \ |
22 | - ((uint64_t)(__buffer)[1] << 8) | \ |
23 | - ((uint64_t)(__buffer)[2] << 16) | \ |
24 | - ((uint64_t)(__buffer)[3] << 24) | \ |
25 | - ((uint64_t)(__buffer)[4] << 32) | \ |
26 | - ((uint64_t)(__buffer)[5] << 40) | \ |
27 | - ((uint64_t)(__buffer)[6] << 48) | \ |
28 | - ((uint64_t)(__buffer)[7] << 56)) |
29 | +#define drizzle_get_byte2(__buffer) \ |
30 | + ((((uint8_t *)__buffer)[0]) | \ |
31 | + ((uint16_t)(((uint8_t *)__buffer)[1]) << 8)) |
32 | +#define drizzle_get_byte3(__buffer) \ |
33 | + (((uint8_t *)__buffer)[0] | \ |
34 | + ((uint32_t)(((uint8_t *)__buffer)[1]) << 8) | \ |
35 | + ((uint32_t)(((uint8_t *)__buffer)[2]) << 16)) |
36 | +#define drizzle_get_byte4(__buffer) \ |
37 | + (((uint8_t *)__buffer)[0] | \ |
38 | + ((uint32_t)(((uint8_t *)__buffer)[1]) << 8) | \ |
39 | + ((uint32_t)(((uint8_t *)__buffer)[2]) << 16) | \ |
40 | + ((uint32_t)(((uint8_t *)__buffer)[3]) << 24)) |
41 | +#define drizzle_get_byte8(__buffer) \ |
42 | + (drizzle_get_byte4(__buffer) | \ |
43 | + ((uint64_t)drizzle_get_byte4(((uint8_t *)__buffer)+4) << 32)) |
44 | |
45 | /* Protocol packing macros. */ |
46 | #define drizzle_set_byte2(__buffer, __int) do { \ |
47 | |
48 | === modified file 'libdrizzle-5.1/field_client.h' |
49 | --- libdrizzle-5.1/field_client.h 2013-01-27 11:55:48 +0000 |
50 | +++ libdrizzle-5.1/field_client.h 2013-03-12 16:48:27 +0000 |
51 | @@ -60,14 +60,29 @@ |
52 | * Read field for unbuffered result, possibly in parts. This is especially |
53 | * useful for blob streaming, since the client does not need to buffer the |
54 | * entire blob. |
55 | + * |
56 | + * The return value is a pointer into a buffer internal to \a result and should |
57 | + * not be freed. It is valid only until the next call to a drizzle function for this |
58 | + * connection. |
59 | + * |
60 | + * @returns A pointer to \a size bytes of field data. |
61 | + * @param[in,out] result The result handle for the response being read. |
62 | + * @param[out] offset The offset within the field of the data that was read. |
63 | + * @param[out] size The number of bytes returned. |
64 | + * @param[out] total The total size of the field being read. |
65 | + * @param[out] ret_ptr DRIZZLE_RETURN_* |
66 | + * |
67 | */ |
68 | DRIZZLE_API |
69 | -drizzle_field_t drizzle_field_read(drizzle_result_st *result, size_t *offset, |
70 | - size_t *size, size_t *total, |
71 | +drizzle_field_t drizzle_field_read(drizzle_result_st *result, uint64_t *offset, |
72 | + size_t *size, uint64_t *total, |
73 | drizzle_return_t *ret_ptr); |
74 | |
75 | /** |
76 | * Buffer one field. |
77 | + * |
78 | + * The return value is a newly allocated buffer and must be freed using drizzle_field_free |
79 | + * when no longer needed. |
80 | */ |
81 | DRIZZLE_API |
82 | drizzle_field_t drizzle_field_buffer(drizzle_result_st *result, size_t *total, |
83 | |
84 | === modified file 'libdrizzle/binlog.cc' |
85 | --- libdrizzle/binlog.cc 2013-01-28 01:04:53 +0000 |
86 | +++ libdrizzle/binlog.cc 2013-03-12 16:48:27 +0000 |
87 | @@ -289,10 +289,10 @@ |
88 | con->packet_size-= 9; |
89 | |
90 | snprintf(con->last_error, DRIZZLE_MAX_ERROR_SIZE, "%.*s", |
91 | - (int32_t)con->packet_size, con->buffer_ptr); |
92 | + (int)con->packet_size, con->buffer_ptr); |
93 | con->last_error[DRIZZLE_MAX_ERROR_SIZE-1]= 0; |
94 | snprintf(con->result->info, DRIZZLE_MAX_INFO_SIZE, "%.*s", |
95 | - (int32_t)con->packet_size, con->buffer_ptr); |
96 | + (int)con->packet_size, con->buffer_ptr); |
97 | con->result->info[DRIZZLE_MAX_INFO_SIZE-1]= 0; |
98 | con->buffer_ptr+= con->packet_size; |
99 | con->buffer_size-= con->packet_size; |
100 | @@ -315,7 +315,7 @@ |
101 | if (con->packet_size != binlog_event->length) |
102 | { |
103 | drizzle_set_error(con, "drizzle_state_binlog_read", |
104 | - "packet size error:%zu:%zu", con->packet_size, binlog_event->length); |
105 | + "packet size error:%"PRIu32":%"PRIu32, con->packet_size, binlog_event->length); |
106 | con->binlog->error_fn(DRIZZLE_RETURN_UNEXPECTED_DATA, con, con->binlog->binlog_context); |
107 | return DRIZZLE_RETURN_UNEXPECTED_DATA; |
108 | } |
109 | @@ -370,10 +370,10 @@ |
110 | memcpy(&binlog_event->checksum, binlog_event->raw_data + (binlog_event->raw_length - DRIZZLE_BINLOG_CRC32_LEN), DRIZZLE_BINLOG_CRC32_LEN); |
111 | if (con->binlog->verify_checksums) |
112 | { |
113 | - event_crc= crc32(0, binlog_event->raw_data, (binlog_event->raw_length - DRIZZLE_BINLOG_CRC32_LEN)); |
114 | + event_crc= (uint32_t)crc32(0, binlog_event->raw_data, (binlog_event->raw_length - DRIZZLE_BINLOG_CRC32_LEN)); |
115 | if (event_crc != binlog_event->checksum) |
116 | { |
117 | - drizzle_set_error(con, __func__, "CRC doesn't match: 0x%lX, 0x%lX", event_crc, binlog_event->checksum); |
118 | + drizzle_set_error(con, __func__, "CRC doesn't match: 0x%"PRIX32", 0x%"PRIX32, event_crc, binlog_event->checksum); |
119 | con->binlog->error_fn(DRIZZLE_RETURN_BINLOG_CRC, con, con->binlog->binlog_context); |
120 | return DRIZZLE_RETURN_BINLOG_CRC; |
121 | } |
122 | |
123 | === modified file 'libdrizzle/conn.cc' |
124 | --- libdrizzle/conn.cc 2013-01-27 11:55:48 +0000 |
125 | +++ libdrizzle/conn.cc 2013-03-12 16:48:27 +0000 |
126 | @@ -724,6 +724,12 @@ |
127 | { |
128 | drizzle_result_st *result; |
129 | drizzle_return_t ret; |
130 | + |
131 | + if (db == NULL) |
132 | + { |
133 | + return DRIZZLE_RETURN_INVALID_ARGUMENT; |
134 | + } |
135 | + |
136 | drizzle_set_db(con, db); |
137 | result= drizzle_command_write(con, NULL, DRIZZLE_COMMAND_INIT_DB, |
138 | db, strlen(db), strlen(db), &ret); |
139 | |
140 | === modified file 'libdrizzle/field.cc' |
141 | --- libdrizzle/field.cc 2013-01-27 11:55:48 +0000 |
142 | +++ libdrizzle/field.cc 2013-03-12 16:48:27 +0000 |
143 | @@ -48,8 +48,8 @@ |
144 | * Client definitions |
145 | */ |
146 | |
147 | -drizzle_field_t drizzle_field_read(drizzle_result_st *result, size_t *offset, |
148 | - size_t *size, size_t *total, |
149 | +drizzle_field_t drizzle_field_read(drizzle_result_st *result, uint64_t *offset, |
150 | + size_t *size, uint64_t *total, |
151 | drizzle_return_t *ret_ptr) |
152 | { |
153 | drizzle_return_t unused_ret; |
154 | @@ -115,8 +115,9 @@ |
155 | drizzle_field_t drizzle_field_buffer(drizzle_result_st *result, size_t *total, |
156 | drizzle_return_t *ret_ptr) |
157 | { |
158 | - size_t offset= 0; |
159 | + uint64_t offset= 0; |
160 | size_t size= 0; |
161 | + uint64_t wire_size; |
162 | |
163 | drizzle_return_t unused_ret; |
164 | if (ret_ptr == NULL) |
165 | @@ -130,7 +131,7 @@ |
166 | return 0; |
167 | } |
168 | |
169 | - drizzle_field_t field= drizzle_field_read(result, &offset, &size, total, ret_ptr); |
170 | + drizzle_field_t field= drizzle_field_read(result, &offset, &size, &wire_size, ret_ptr); |
171 | |
172 | if (*ret_ptr != DRIZZLE_RETURN_OK) |
173 | { |
174 | @@ -143,6 +144,14 @@ |
175 | return NULL; |
176 | } |
177 | |
178 | + if ((SIZE_MAX < UINT64_MAX) && (wire_size >= SIZE_MAX)) |
179 | + { |
180 | + drizzle_set_error(result->con, __func__, "Field is larger than memory."); |
181 | + *ret_ptr= DRIZZLE_RETURN_MEMORY; |
182 | + return NULL; |
183 | + } |
184 | + *total = (size_t)wire_size; |
185 | + |
186 | if (result->field_buffer == NULL) |
187 | { |
188 | result->field_buffer= new (std::nothrow) char[(*total) + 1]; |
189 | @@ -158,12 +167,13 @@ |
190 | |
191 | while ((offset + size) != (*total)) |
192 | { |
193 | - field= drizzle_field_read(result, &offset, &size, total, ret_ptr); |
194 | + field= drizzle_field_read(result, &offset, &size, &wire_size, ret_ptr); |
195 | if (*ret_ptr != DRIZZLE_RETURN_OK) |
196 | { |
197 | return NULL; |
198 | } |
199 | - |
200 | + assert(wire_size == (uint64_t)*total); |
201 | + |
202 | memcpy(result->field_buffer + offset, field, size); |
203 | } |
204 | |
205 | @@ -207,7 +217,7 @@ |
206 | con->result->field_size= 0; |
207 | |
208 | drizzle_return_t ret; |
209 | - con->result->field_total= (size_t)drizzle_unpack_length(con, &ret); |
210 | + con->result->field_total= drizzle_unpack_length(con, &ret); |
211 | if (ret == DRIZZLE_RETURN_NULL_SIZE) |
212 | { |
213 | con->result->field= NULL; |
214 | @@ -227,35 +237,43 @@ |
215 | } |
216 | |
217 | drizzle_log_debug(con, |
218 | - "field_offset= %zu, field_size= %zu, field_total= %zu", |
219 | + "field_offset= %"PRIu64", field_size= %zu, field_total= %"PRIu64, |
220 | con->result->field_offset, con->result->field_size, |
221 | con->result->field_total); |
222 | |
223 | - if ((size_t)(con->buffer_size) >= con->result->field_total) |
224 | + uint32_t available_data = (con->buffer_size < con->packet_size)? (uint32_t)con->buffer_size : con->packet_size; |
225 | + /* packet_size fits in uint32, so available_data fits in uint32 */ |
226 | + |
227 | + if (available_data >= con->result->field_total) |
228 | { |
229 | - con->result->field_size= con->result->field_total; |
230 | + /* narrowing cast is safe because field_total<packet_size and packet_size is uint32 */ |
231 | + con->result->field_size= (uint32_t)con->result->field_total; |
232 | } |
233 | else |
234 | { |
235 | - con->result->field_size= con->buffer_size; |
236 | + con->result->field_size= available_data; |
237 | } |
238 | } |
239 | else |
240 | { |
241 | - if ((con->result->field_offset + con->buffer_size) >= |
242 | - con->result->field_total) |
243 | + uint32_t available_data = (con->buffer_size < con->packet_size)? (uint32_t)con->buffer_size : con->packet_size; |
244 | + /* packet_size fits in uint32, so available_data fits in uint32 */ |
245 | + |
246 | + uint64_t field_remaining = con->result->field_total - con->result->field_offset; |
247 | + |
248 | + if (field_remaining <= available_data) |
249 | { |
250 | - con->result->field_size= (con->result->field_total - |
251 | - con->result->field_offset); |
252 | + /* narrowing cast is safe because field_remaining<=packet_size and packet_size is uint32 */ |
253 | + con->result->field_size= (uint32_t)field_remaining; |
254 | } |
255 | else |
256 | { |
257 | - con->result->field_size= con->buffer_size; |
258 | + con->result->field_size= available_data; |
259 | } |
260 | } |
261 | |
262 | /* This is a special case when a row is larger than the packet size. */ |
263 | - if (con->result->field_size > (size_t)con->packet_size) |
264 | + if (con->result->field_size > con->packet_size) |
265 | { |
266 | con->result->field_size= con->packet_size; |
267 | |
268 | @@ -277,7 +295,7 @@ |
269 | con->packet_size-= con->result->field_size; |
270 | |
271 | drizzle_log_debug(con, |
272 | - "field_offset= %zu, field_size= %zu, field_total= %zu", |
273 | + "field_offset= %"PRIu64", field_size= %zu, field_total= %"PRIu64, |
274 | con->result->field_offset, con->result->field_size, |
275 | con->result->field_total); |
276 | |
277 | |
278 | === modified file 'libdrizzle/handshake.cc' |
279 | --- libdrizzle/handshake.cc 2013-01-27 11:55:48 +0000 |
280 | +++ libdrizzle/handshake.cc 2013-03-12 16:48:27 +0000 |
281 | @@ -83,7 +83,7 @@ |
282 | drizzle_return_t drizzle_state_handshake_server_read(drizzle_st *con) |
283 | { |
284 | unsigned char *ptr; |
285 | - int extra_length; |
286 | + ptrdiff_t extra_length; |
287 | unsigned char* packet_end; |
288 | |
289 | if (con == NULL) |
290 | @@ -117,7 +117,7 @@ |
291 | if (con->protocol_version == 255) |
292 | { |
293 | drizzle_set_error(con, "drizzle_state_handshake_server_read", |
294 | - "%.*s", (int32_t)con->packet_size - 3, |
295 | + "%.*s", (int)con->packet_size - 3, |
296 | con->buffer_ptr + 2); |
297 | return DRIZZLE_RETURN_AUTH_FAILED; |
298 | } |
299 | |
300 | === modified file 'libdrizzle/pack.cc' |
301 | --- libdrizzle/pack.cc 2013-01-27 11:55:48 +0000 |
302 | +++ libdrizzle/pack.cc 2013-03-12 16:48:27 +0000 |
303 | @@ -165,12 +165,12 @@ |
304 | return NULL; |
305 | } |
306 | |
307 | - uint64_t size= strlen(string); |
308 | + size_t size= strlen(string); |
309 | |
310 | ptr= drizzle_pack_length(size, ptr); |
311 | if (size > 0) |
312 | { |
313 | - memcpy(ptr, string, (size_t)size); |
314 | + memcpy(ptr, string, size); |
315 | ptr+= size; |
316 | } |
317 | |
318 | @@ -292,7 +292,7 @@ |
319 | } |
320 | |
321 | drizzle_return_t drizzle_unpack_string(drizzle_st *con, char *buffer, |
322 | - uint64_t max_length) |
323 | + size_t max_length) |
324 | { |
325 | drizzle_return_t ret= DRIZZLE_RETURN_OK; |
326 | |
327 | @@ -313,6 +313,18 @@ |
328 | return ret; |
329 | } |
330 | |
331 | + if (length > con->packet_size) |
332 | + { |
333 | + drizzle_set_error(con, "drizzle_unpack_string", |
334 | + "string extends past end of packet"); |
335 | + return DRIZZLE_RETURN_UNEXPECTED_DATA; |
336 | + } |
337 | + if (length > con->buffer_size) |
338 | + { |
339 | + return DRIZZLE_RETURN_IO_WAIT; |
340 | + } |
341 | + |
342 | + assert(max_length > 1); |
343 | if (length < max_length) |
344 | { |
345 | if (length > 0) |
346 | @@ -322,13 +334,13 @@ |
347 | } |
348 | else |
349 | { |
350 | - memcpy(buffer, con->buffer_ptr, (size_t)(max_length - 1)); |
351 | + memcpy(buffer, con->buffer_ptr, max_length - 1); |
352 | buffer[max_length - 1]= 0; |
353 | } |
354 | - |
355 | + |
356 | con->buffer_ptr+= length; |
357 | - con->buffer_size-= (size_t)length; |
358 | - con->packet_size-= (size_t)length; |
359 | + con->buffer_size-= length; |
360 | + con->packet_size-= (uint32_t)length; |
361 | |
362 | return DRIZZLE_RETURN_OK; |
363 | } |
364 | |
365 | === modified file 'libdrizzle/pack.h' |
366 | --- libdrizzle/pack.h 2013-01-27 11:55:48 +0000 |
367 | +++ libdrizzle/pack.h 2013-03-12 16:48:27 +0000 |
368 | @@ -85,9 +85,10 @@ |
369 | |
370 | /** |
371 | * Unpack length-encoded string. |
372 | + * max_size is a size_t because it describes the size of the in-core 'buffer'. |
373 | */ |
374 | drizzle_return_t drizzle_unpack_string(drizzle_st *con, char *buffer, |
375 | - uint64_t max_size); |
376 | + size_t max_size); |
377 | |
378 | /** |
379 | * Pack user, scramble, and db. |
380 | |
381 | === modified file 'libdrizzle/result.cc' |
382 | --- libdrizzle/result.cc 2013-01-27 14:00:17 +0000 |
383 | +++ libdrizzle/result.cc 2013-03-12 16:48:27 +0000 |
384 | @@ -314,16 +314,20 @@ |
385 | |
386 | if (result->row_list_size < result->row_count) |
387 | { |
388 | - row_list= (drizzle_row_t *)realloc(result->row_list, sizeof(drizzle_row_t) * ((size_t)(result->row_list_size) + DRIZZLE_ROW_GROW_SIZE)); |
389 | + size_t new_row_list_size = result->row_list_size + DRIZZLE_ROW_GROW_SIZE; |
390 | + |
391 | + row_list= (drizzle_row_t *)realloc(result->row_list, sizeof(drizzle_row_t) * new_row_list_size); |
392 | if (row_list == NULL) |
393 | { |
394 | drizzle_row_free(result, row); |
395 | drizzle_set_error(result->con, __func__, "Failed to realloc row_list."); |
396 | return DRIZZLE_RETURN_MEMORY; |
397 | } |
398 | + result->row_list= row_list; |
399 | + |
400 | if (result->binary_rows) |
401 | { |
402 | - uint8_t **null_bitmap_list= (uint8_t**)realloc(result->null_bitmap_list, sizeof(uint8_t*) * ((size_t)(result->row_list_size) + DRIZZLE_ROW_GROW_SIZE)); |
403 | + uint8_t **null_bitmap_list= (uint8_t **)realloc(result->null_bitmap_list, sizeof(uint8_t *) * new_row_list_size); |
404 | if (null_bitmap_list == NULL) |
405 | { |
406 | drizzle_row_free(result, row); |
407 | @@ -332,19 +336,17 @@ |
408 | } |
409 | result->null_bitmap_list= null_bitmap_list; |
410 | } |
411 | - result->row_list= row_list; |
412 | |
413 | - field_sizes_list= (size_t **)realloc(result->field_sizes_list, sizeof(size_t *) * ((size_t)(result->row_list_size) + DRIZZLE_ROW_GROW_SIZE)); |
414 | + field_sizes_list= (size_t **)realloc(result->field_sizes_list, sizeof(size_t *) * new_row_list_size); |
415 | if (field_sizes_list == NULL) |
416 | { |
417 | drizzle_row_free(result, row); |
418 | drizzle_set_error(result->con, "drizzle_result_buffer", "Failed to realloc field list."); |
419 | return DRIZZLE_RETURN_MEMORY; |
420 | } |
421 | - |
422 | result->field_sizes_list= field_sizes_list; |
423 | |
424 | - result->row_list_size+= DRIZZLE_ROW_GROW_SIZE; |
425 | + result->row_list_size= new_row_list_size; |
426 | } |
427 | |
428 | if (result->binary_rows) |
429 | @@ -460,10 +462,10 @@ |
430 | if (con->packet_size > 0) |
431 | { |
432 | snprintf(con->last_error, DRIZZLE_MAX_ERROR_SIZE, "%.*s", |
433 | - (int32_t)con->packet_size, con->buffer_ptr); |
434 | + (int)con->packet_size, con->buffer_ptr); |
435 | con->last_error[DRIZZLE_MAX_ERROR_SIZE-1]= 0; |
436 | snprintf(con->result->info, DRIZZLE_MAX_INFO_SIZE, "%.*s", |
437 | - (int32_t)con->packet_size, con->buffer_ptr); |
438 | + (int)con->packet_size, con->buffer_ptr); |
439 | con->result->info[DRIZZLE_MAX_INFO_SIZE-1]= 0; |
440 | con->buffer_ptr+= con->packet_size; |
441 | con->buffer_size-= con->packet_size; |
442 | |
443 | === modified file 'libdrizzle/result.h' |
444 | --- libdrizzle/result.h 2013-01-27 11:22:49 +0000 |
445 | +++ libdrizzle/result.h 2013-03-12 16:48:27 +0000 |
446 | @@ -64,14 +64,14 @@ |
447 | uint64_t row_count; |
448 | uint64_t row_current; |
449 | |
450 | - uint16_t field_current; |
451 | - size_t field_total; |
452 | - size_t field_offset; |
453 | - size_t field_size; |
454 | + uint16_t field_current; /* field index */ |
455 | + uint64_t field_total; /* total length of the field currently being read */ |
456 | + uint64_t field_offset; /* offset within field of most recently read field fragment (0 if first/only fragment) */ |
457 | + uint32_t field_size; /* size of most recently read field value or fragment of field value; max 2^24 */ |
458 | drizzle_field_t field; |
459 | drizzle_field_t field_buffer; |
460 | |
461 | - uint64_t row_list_size; |
462 | + size_t row_list_size; |
463 | drizzle_row_t row; |
464 | drizzle_row_t *row_list; |
465 | size_t *field_sizes; |
466 | @@ -80,7 +80,7 @@ |
467 | bool binlog_checksums; |
468 | uint8_t **null_bitmap_list; |
469 | uint8_t *null_bitmap; |
470 | - uint8_t null_bitmap_length; |
471 | + uint16_t null_bitmap_length; |
472 | bool binary_rows; |
473 | |
474 | drizzle_result_st() : |
475 | |
476 | === modified file 'libdrizzle/statement.cc' |
477 | --- libdrizzle/statement.cc 2013-01-27 09:48:19 +0000 |
478 | +++ libdrizzle/statement.cc 2013-03-12 16:48:27 +0000 |
479 | @@ -320,7 +320,7 @@ |
480 | |
481 | if (stmt->state < DRIZZLE_STMT_PREPARED) |
482 | { |
483 | - drizzle_set_error(stmt->con, __func__, "stmt object has bot been prepared"); |
484 | + drizzle_set_error(stmt->con, __func__, "stmt object has not been prepared"); |
485 | return DRIZZLE_RETURN_STMT_ERROR; |
486 | } |
487 | |
488 | |
489 | === modified file 'libdrizzle/statement_param.cc' |
490 | --- libdrizzle/statement_param.cc 2013-01-27 11:55:48 +0000 |
491 | +++ libdrizzle/statement_param.cc 2013-03-12 16:48:27 +0000 |
492 | @@ -47,7 +47,7 @@ |
493 | } |
494 | if (stmt->state < DRIZZLE_STMT_PREPARED) |
495 | { |
496 | - drizzle_set_error(stmt->con, __func__, "stmt object has bot been prepared"); |
497 | + drizzle_set_error(stmt->con, __func__, "stmt object has not been prepared"); |
498 | return DRIZZLE_RETURN_STMT_ERROR; |
499 | } |
500 | |
501 | @@ -165,6 +165,7 @@ |
502 | if ((stmt == NULL) || (stmt->result_params == NULL)) |
503 | { |
504 | *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT; |
505 | + return 0; |
506 | } |
507 | column_number= drizzle_stmt_column_lookup(stmt->prepare_result, column_name, ret_ptr); |
508 | if (*ret_ptr != DRIZZLE_RETURN_OK) |
509 | @@ -192,6 +193,7 @@ |
510 | if ((stmt == NULL) || (stmt->result_params == NULL)) |
511 | { |
512 | *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT; |
513 | + return 0; |
514 | } |
515 | column_number= drizzle_stmt_column_lookup(stmt->prepare_result, column_name, ret_ptr); |
516 | if (*ret_ptr != DRIZZLE_RETURN_OK) |
517 | @@ -219,6 +221,7 @@ |
518 | if ((stmt == NULL) || (stmt->result_params == NULL)) |
519 | { |
520 | *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT; |
521 | + return 0; |
522 | } |
523 | column_number= drizzle_stmt_column_lookup(stmt->prepare_result, column_name, ret_ptr); |
524 | if (*ret_ptr != DRIZZLE_RETURN_OK) |
525 | @@ -318,6 +321,7 @@ |
526 | if ((stmt == NULL) || (stmt->result_params == NULL)) |
527 | { |
528 | *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT; |
529 | + return 0; |
530 | } |
531 | column_number= drizzle_stmt_column_lookup(stmt->prepare_result, column_name, ret_ptr); |
532 | if (*ret_ptr != DRIZZLE_RETURN_OK) |
533 | @@ -407,6 +411,7 @@ |
534 | if ((stmt == NULL) || (stmt->result_params == NULL)) |
535 | { |
536 | *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT; |
537 | + return 0; |
538 | } |
539 | column_number= drizzle_stmt_column_lookup(stmt->prepare_result, column_name, ret_ptr); |
540 | if (*ret_ptr != DRIZZLE_RETURN_OK) |
541 | @@ -418,7 +423,7 @@ |
542 | |
543 | uint64_t drizzle_stmt_get_bigint(drizzle_stmt_st *stmt, uint16_t column_number, drizzle_return_t *ret_ptr) |
544 | { |
545 | - uint32_t val; |
546 | + uint64_t val; |
547 | drizzle_bind_st *param; |
548 | |
549 | if ((stmt == NULL) || (stmt->result_params == NULL) || (column_number >= stmt->execute_result->column_count)) |
550 | @@ -492,6 +497,7 @@ |
551 | if ((stmt == NULL) || (stmt->result_params == NULL)) |
552 | { |
553 | *ret_ptr= DRIZZLE_RETURN_INVALID_ARGUMENT; |
554 | + return 0; |
555 | } |
556 | column_number= drizzle_stmt_column_lookup(stmt->prepare_result, column_name, ret_ptr); |
557 | if (*ret_ptr != DRIZZLE_RETURN_OK) |
558 | |
559 | === modified file 'libdrizzle/structs.h' |
560 | --- libdrizzle/structs.h 2013-01-27 14:00:17 +0000 |
561 | +++ libdrizzle/structs.h 2013-03-12 16:48:27 +0000 |
562 | @@ -208,13 +208,13 @@ |
563 | uint32_t thread_id; |
564 | int backlog; |
565 | socket_t fd; |
566 | - size_t buffer_size; |
567 | + size_t buffer_size; /* amount of valid data after 'buffer_ptr' in 'buffer' */ |
568 | size_t command_offset; |
569 | size_t command_size; |
570 | size_t command_total; |
571 | - size_t packet_size; |
572 | + uint32_t packet_size; /* remaining number of bytes in packet currently being read; maximum value 2^24 */ |
573 | struct addrinfo *addrinfo_next; |
574 | - unsigned char *buffer_ptr; |
575 | + unsigned char *buffer_ptr; /* cursor pointing into 'buffer' */ |
576 | unsigned char *command_buffer; |
577 | unsigned char *command_data; |
578 | void *context; |
579 | @@ -228,7 +228,7 @@ |
580 | drizzle_uds_st uds; |
581 | } socket; |
582 | unsigned char *buffer; |
583 | - size_t buffer_allocation; |
584 | + size_t buffer_allocation; /* total allocated size of 'buffer' */ |
585 | char db[DRIZZLE_MAX_DB_SIZE]; |
586 | char password[DRIZZLE_MAX_PASSWORD_SIZE]; |
587 | unsigned char scramble_buffer[DRIZZLE_MAX_SCRAMBLE_SIZE]; |
588 | @@ -492,7 +492,7 @@ |
589 | uint16_t param_count; |
590 | drizzle_bind_st *query_params; |
591 | drizzle_bind_st *result_params; |
592 | - uint8_t null_bitmap_length; |
593 | + uint16_t null_bitmap_length; |
594 | uint8_t *null_bitmap; |
595 | bool new_bind; |
596 | drizzle_result_st *prepare_result; |
597 | @@ -520,7 +520,7 @@ |
598 | drizzle_column_type_t type; |
599 | void *data; |
600 | char *data_buffer; |
601 | - uint32_t length; |
602 | + size_t length; /* amount of data in 'data' */ |
603 | bool is_bound; |
604 | struct options_t |
605 | { |
606 | |
607 | === modified file 'tests/unit/statement.c' |
608 | --- tests/unit/statement.c 2013-01-27 09:48:19 +0000 |
609 | +++ tests/unit/statement.c 2013-03-12 16:48:27 +0000 |
610 | @@ -103,7 +103,7 @@ |
611 | ASSERT_EQ_(DRIZZLE_RETURN_OK, ret, "%s", drizzle_error(con)); |
612 | |
613 | /* Result should have 2 rows */ |
614 | - int count= drizzle_stmt_row_count(stmt); |
615 | + uint64_t count = drizzle_stmt_row_count(stmt); |
616 | ASSERT_EQ_(2, count, "%s", drizzle_error(con)); |
617 | |
618 | uint32_t i= 1; |
Very nice catches in there, most of them my silly mistakes, especially around prepared stmt :)
Worst case this slightly breaks API on the drizzle_field functions, but only for 32bit so I'm not so concerned.