Bug #5960 A consistent read of an updated row with BLOB or TEXT col can return garbage
| Submitted: | 7 Oct 2004 18:42 | Modified: | 30 Oct 2004 8:53 |
|---|---|---|---|
| Reporter: | Heikki Tuuri | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: InnoDB storage engine | Severity: | S2 (Serious) |
| Version: | All | OS: | |
| Assigned to: | Heikki Tuuri | CPU Architecture: | Any |
[7 Oct 2004 18:48]
Heikki Tuuri
This bug is only in InnoDB.
[30 Oct 2004 8:53]
Heikki Tuuri
Fixed in 4.0.22.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.038 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: Hi! If one updates a row so that the size of some column value changes, but the value of a BLOB or a TEXT column does not change, then a consistent read of the previous version of the BLOB or TEXT will bring at most 532 bytes of data, of which 512 bytes is good data, and the remaining 20 bytes the 'external storage header', that is, nonprintable characters. This bug was found by a user. Will be fixed in 4.0.22. Regards, Heikki How to repeat: See above. Suggested fix: Do not forget columns with the external bit set in the original row: if (row_upd_changes_field_size_or_external(rec, index, update)) { entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); row_upd_index_replace_new_col_vals(entry, index, update, heap); buf = mem_heap_alloc(heap, rec_get_converted_size(entry)); *old_vers = rec_convert_dtuple_to_rec(buf, entry); } else { buf = mem_heap_alloc(heap, rec_get_size(rec)); *old_vers = rec_copy(buf, rec); row_upd_rec_in_place(*old_vers, update); } for (i = 0; i < upd_get_n_fields(update); i++) { if (upd_get_nth_field(update, i)->extern_storage) { rec_set_nth_field_extern_bit(*old_vers, upd_get_nth_field(update, i)->field_no, TRUE, NULL); } } return(DB_SUCCESS);