mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-04-05 20:31:00 +08:00
Fix some issues with mdb_memo_to_string
This commit is contained in:
parent
3153f5dd1e
commit
07c9d00283
@ -1,3 +1,8 @@
|
||||
Fri Mar 11 21:32:19 CST 2005 Jeff Smith <whydoubt@yahoo.com>
|
||||
* HACKING:
|
||||
* src/libmdb/data.c:
|
||||
* src/libmdb/iconv.c: Fix some issues with mdb_memo_to_string
|
||||
|
||||
Sun Mar 6 22:09:09 CST 2005 Jeff Smith <whydoubt@yahoo.com>
|
||||
* src/libmdb/table.c: Fix memory leak
|
||||
* include/mdbtools.h:
|
||||
|
10
HACKING
10
HACKING
@ -199,16 +199,16 @@ Each memo column (or other long binary data) in a row
|
||||
+------+---------+-------------+------------------------------------------+
|
||||
| data | length | name | description |
|
||||
+------+---------+-------------+------------------------------------------+
|
||||
| ???? | 2 bytes | memo_len | Total length of the memo |
|
||||
| ???? | 2 bytes | bitmask | See values |
|
||||
| ???? | 3 bytes | memo_len | Total length of the memo |
|
||||
| ???? | 1 bytes | bitmask | See values |
|
||||
| ???? | 4 bytes | lval_dp | Data pointer to LVAL page (if needed) |
|
||||
| 0x00 | 4 bytes | unknown | |
|
||||
+------+---------+-------------+------------------------------------------+
|
||||
Values for the bitmask:
|
||||
|
||||
0x8000= the memo is in a string at the end of this header (memo_len bytes)
|
||||
0x4000= the memo is in a unique LVAL page in a record type 1
|
||||
0x0000= the memo is in n LVAL pages in a record type 2
|
||||
0x80 = the memo is in a string at the end of this header (memo_len bytes)
|
||||
0x40 = the memo is in a unique LVAL page in a record type 1
|
||||
0x00 = the memo is in n LVAL pages in a record type 2
|
||||
|
||||
If the memo is in a LVAL page, we use row_id of lval_dp to find the row.
|
||||
offset_start of memo = (int16*) LVAL_page[offset_num_rows + (row_id * 2) + 2]
|
||||
|
@ -605,8 +605,7 @@ int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size)
|
||||
}
|
||||
static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
|
||||
{
|
||||
guint16 memo_len;
|
||||
guint16 memo_flags;
|
||||
guint32 memo_len;
|
||||
guint32 row_start, pg_row;
|
||||
guint32 len;
|
||||
char *buf;
|
||||
@ -618,21 +617,22 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
|
||||
}
|
||||
|
||||
#if MDB_DEBUG
|
||||
buffer_dump(mdb->pg_buf, start, start + MDB_MEMO_OVERHEAD);
|
||||
buffer_dump(mdb->pg_buf, start, start + MDB_MEMO_OVERHEAD - 1);
|
||||
#endif
|
||||
|
||||
/* The 16 bit integer at offset 0 is the length of the memo field.
|
||||
/* The 32 bit integer at offset 0 is the length of the memo field
|
||||
* with some flags in the high bits.
|
||||
* The 32 bit integer at offset 4 contains page and row information.
|
||||
*/
|
||||
memo_len = mdb_pg_get_int16(mdb, start);
|
||||
memo_flags = mdb_pg_get_int16(mdb, start+2);
|
||||
memo_len = mdb_pg_get_int32(mdb, start);
|
||||
|
||||
if (memo_flags & 0x8000) {
|
||||
if (memo_len & 0x80000000) {
|
||||
/* inline memo field */
|
||||
mdb_unicode2ascii(mdb, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
|
||||
size - MDB_MEMO_OVERHEAD, text, MDB_BIND_SIZE);
|
||||
return text;
|
||||
} else if (memo_flags & 0x4000) {
|
||||
} else if (memo_len & 0x40000000) {
|
||||
/* single-page memo field */
|
||||
pg_row = mdb_get_int32(mdb->pg_buf, start+4);
|
||||
#if MDB_DEBUG
|
||||
printf("Reading LVAL page %06x\n", pg_row >> 8);
|
||||
@ -644,20 +644,24 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
|
||||
#if MDB_DEBUG
|
||||
printf("row num %d start %d len %d\n",
|
||||
pg_row & 0xff, row_start, len);
|
||||
buffer_dump(mdb->pg_buf, row_start, row_start + len);
|
||||
buffer_dump(buf, row_start, row_start + len - 1);
|
||||
#endif
|
||||
mdb_unicode2ascii(mdb, buf + row_start, len, text, MDB_BIND_SIZE);
|
||||
return text;
|
||||
} else { /* if (memo_flags == 0x0000) { */
|
||||
} else {
|
||||
/* multi-page memo field */
|
||||
int tmpoff = 0;
|
||||
char *tmp;
|
||||
|
||||
memo_len &= 0x3fffffff;
|
||||
tmp = (char *) g_malloc(memo_len);
|
||||
pg_row = mdb_get_int32(mdb->pg_buf, start+4);
|
||||
#if MDB_DEBUG
|
||||
printf("Reading LVAL page %06x\n", pg_row >> 8);
|
||||
#endif
|
||||
tmp = (char *) g_malloc(MDB_BIND_SIZE);
|
||||
tmp[0] = '\0';
|
||||
do {
|
||||
#if MDB_DEBUG
|
||||
printf("Reading LVAL page %06x\n", pg_row >> 8);
|
||||
#endif
|
||||
if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) {
|
||||
g_free(tmp);
|
||||
strcpy(text, "");
|
||||
return text;
|
||||
}
|
||||
@ -665,14 +669,16 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
|
||||
printf("row num %d start %d len %d\n",
|
||||
pg_row & 0xff, row_start, len);
|
||||
#endif
|
||||
strncat(tmp, buf + row_start + 4,
|
||||
strlen(tmp) + len - 4 > MDB_BIND_SIZE ?
|
||||
MDB_BIND_SIZE - strlen(tmp) : len - 4);
|
||||
|
||||
/* find next lval page */
|
||||
pg_row = mdb_get_int32(mdb->pg_buf, row_start);
|
||||
} while ((pg_row >> 8));
|
||||
mdb_unicode2ascii(mdb, tmp, strlen(tmp), text, MDB_BIND_SIZE);
|
||||
if (tmpoff + len - 4 > memo_len) {
|
||||
break;
|
||||
}
|
||||
memcpy(tmp + tmpoff, buf + row_start + 4, len - 4);
|
||||
tmpoff += len - 4;
|
||||
} while (( pg_row = mdb_get_int32(buf, row_start) ));
|
||||
if (tmpoff < memo_len) {
|
||||
fprintf(stderr, "Warning: incorrect memo length\n");
|
||||
}
|
||||
mdb_unicode2ascii(mdb, tmp, tmpoff, text, MDB_BIND_SIZE);
|
||||
g_free(tmp);
|
||||
return text;
|
||||
/*
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "mdbtools.h"
|
||||
#include "errno.h"
|
||||
|
||||
#ifdef DMALLOC
|
||||
#include "dmalloc.h"
|
||||
@ -69,7 +70,7 @@ mdb_unicode2ascii(MdbHandle *mdb, unsigned char *src, unsigned int slen, unsigne
|
||||
//printf("1 len_in %d len_out %d\n",len_in, len_out);
|
||||
while (1) {
|
||||
iconv(mdb->iconv_in, &in_ptr, &len_in, &out_ptr, &len_out);
|
||||
if (!len_in) break;
|
||||
if ((!len_in) || (errno == E2BIG)) break;
|
||||
/* Don't bail if impossible conversion is encountered */
|
||||
in_ptr += (IS_JET4(mdb)) ? 2 : 1;
|
||||
len_in -= (IS_JET4(mdb)) ? 2 : 1;
|
||||
|
Loading…
Reference in New Issue
Block a user