mirror of
https://github.com/mdbtools/mdbtools.git
synced 2025-09-20 11:07:53 +08:00
Fix some issues with mdb_memo_to_string
This commit is contained in:
@@ -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>
|
Sun Mar 6 22:09:09 CST 2005 Jeff Smith <whydoubt@yahoo.com>
|
||||||
* src/libmdb/table.c: Fix memory leak
|
* src/libmdb/table.c: Fix memory leak
|
||||||
* include/mdbtools.h:
|
* 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 |
|
| data | length | name | description |
|
||||||
+------+---------+-------------+------------------------------------------+
|
+------+---------+-------------+------------------------------------------+
|
||||||
| ???? | 2 bytes | memo_len | Total length of the memo |
|
| ???? | 3 bytes | memo_len | Total length of the memo |
|
||||||
| ???? | 2 bytes | bitmask | See values |
|
| ???? | 1 bytes | bitmask | See values |
|
||||||
| ???? | 4 bytes | lval_dp | Data pointer to LVAL page (if needed) |
|
| ???? | 4 bytes | lval_dp | Data pointer to LVAL page (if needed) |
|
||||||
| 0x00 | 4 bytes | unknown | |
|
| 0x00 | 4 bytes | unknown | |
|
||||||
+------+---------+-------------+------------------------------------------+
|
+------+---------+-------------+------------------------------------------+
|
||||||
Values for the bitmask:
|
Values for the bitmask:
|
||||||
|
|
||||||
0x8000= the memo is in a string at the end of this header (memo_len bytes)
|
0x80 = 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
|
0x40 = 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
|
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.
|
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]
|
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)
|
static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
|
||||||
{
|
{
|
||||||
guint16 memo_len;
|
guint32 memo_len;
|
||||||
guint16 memo_flags;
|
|
||||||
guint32 row_start, pg_row;
|
guint32 row_start, pg_row;
|
||||||
guint32 len;
|
guint32 len;
|
||||||
char *buf;
|
char *buf;
|
||||||
@@ -618,21 +617,22 @@ static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if MDB_DEBUG
|
#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
|
#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.
|
* The 32 bit integer at offset 4 contains page and row information.
|
||||||
*/
|
*/
|
||||||
memo_len = mdb_pg_get_int16(mdb, start);
|
memo_len = mdb_pg_get_int32(mdb, start);
|
||||||
memo_flags = mdb_pg_get_int16(mdb, start+2);
|
|
||||||
|
|
||||||
if (memo_flags & 0x8000) {
|
if (memo_len & 0x80000000) {
|
||||||
/* inline memo field */
|
/* inline memo field */
|
||||||
mdb_unicode2ascii(mdb, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
|
mdb_unicode2ascii(mdb, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
|
||||||
size - MDB_MEMO_OVERHEAD, text, MDB_BIND_SIZE);
|
size - MDB_MEMO_OVERHEAD, text, MDB_BIND_SIZE);
|
||||||
return text;
|
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);
|
pg_row = mdb_get_int32(mdb->pg_buf, start+4);
|
||||||
#if MDB_DEBUG
|
#if MDB_DEBUG
|
||||||
printf("Reading LVAL page %06x\n", pg_row >> 8);
|
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
|
#if MDB_DEBUG
|
||||||
printf("row num %d start %d len %d\n",
|
printf("row num %d start %d len %d\n",
|
||||||
pg_row & 0xff, row_start, len);
|
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
|
#endif
|
||||||
mdb_unicode2ascii(mdb, buf + row_start, len, text, MDB_BIND_SIZE);
|
mdb_unicode2ascii(mdb, buf + row_start, len, text, MDB_BIND_SIZE);
|
||||||
return text;
|
return text;
|
||||||
} else { /* if (memo_flags == 0x0000) { */
|
} else {
|
||||||
|
/* multi-page memo field */
|
||||||
|
int tmpoff = 0;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
|
memo_len &= 0x3fffffff;
|
||||||
|
tmp = (char *) g_malloc(memo_len);
|
||||||
pg_row = mdb_get_int32(mdb->pg_buf, start+4);
|
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 {
|
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)) {
|
if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) {
|
||||||
|
g_free(tmp);
|
||||||
strcpy(text, "");
|
strcpy(text, "");
|
||||||
return 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",
|
printf("row num %d start %d len %d\n",
|
||||||
pg_row & 0xff, row_start, len);
|
pg_row & 0xff, row_start, len);
|
||||||
#endif
|
#endif
|
||||||
strncat(tmp, buf + row_start + 4,
|
if (tmpoff + len - 4 > memo_len) {
|
||||||
strlen(tmp) + len - 4 > MDB_BIND_SIZE ?
|
break;
|
||||||
MDB_BIND_SIZE - strlen(tmp) : len - 4);
|
}
|
||||||
|
memcpy(tmp + tmpoff, buf + row_start + 4, len - 4);
|
||||||
/* find next lval page */
|
tmpoff += len - 4;
|
||||||
pg_row = mdb_get_int32(mdb->pg_buf, row_start);
|
} while (( pg_row = mdb_get_int32(buf, row_start) ));
|
||||||
} while ((pg_row >> 8));
|
if (tmpoff < memo_len) {
|
||||||
mdb_unicode2ascii(mdb, tmp, strlen(tmp), text, MDB_BIND_SIZE);
|
fprintf(stderr, "Warning: incorrect memo length\n");
|
||||||
|
}
|
||||||
|
mdb_unicode2ascii(mdb, tmp, tmpoff, text, MDB_BIND_SIZE);
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
return text;
|
return text;
|
||||||
/*
|
/*
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mdbtools.h"
|
#include "mdbtools.h"
|
||||||
|
#include "errno.h"
|
||||||
|
|
||||||
#ifdef DMALLOC
|
#ifdef DMALLOC
|
||||||
#include "dmalloc.h"
|
#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);
|
//printf("1 len_in %d len_out %d\n",len_in, len_out);
|
||||||
while (1) {
|
while (1) {
|
||||||
iconv(mdb->iconv_in, &in_ptr, &len_in, &out_ptr, &len_out);
|
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 */
|
/* Don't bail if impossible conversion is encountered */
|
||||||
in_ptr += (IS_JET4(mdb)) ? 2 : 1;
|
in_ptr += (IS_JET4(mdb)) ? 2 : 1;
|
||||||
len_in -= (IS_JET4(mdb)) ? 2 : 1;
|
len_in -= (IS_JET4(mdb)) ? 2 : 1;
|
||||||
|
Reference in New Issue
Block a user