#define HIVEX_MAX_ALLOCATION 1000000
static char *windows_utf16_to_utf8 (/* const */ char *input, size_t len);
+static size_t utf16_string_len_in_bytes_max (const char *str, size_t len);
struct hive_h {
char *filename;
{
int r;
+ if (h->msglvl >= 1)
+ fprintf (stderr, "hivex_close\n");
+
free (h->bitmap);
if (!h->writable)
munmap (h->addr, h->size);
fprintf (stderr, "hivex_value_value: warning: declared data length is longer than the block it is in (data 0x%zx, data len %zu, block len %zu)\n",
data_offset, len, blen);
len = blen - 4;
+
+ /* Return the smaller length to the caller too. */
+ if (len_rtn)
+ *len_rtn = len;
}
char *data = h->addr + data_offset + 4;
return NULL;
}
+ /* Deal with the case where Windows has allocated a large buffer
+ * full of random junk, and only the first few bytes of the buffer
+ * contain a genuine UTF-16 string.
+ *
+ * In this case, iconv would try to process the junk bytes as UTF-16
+ * and inevitably find an illegal sequence (EILSEQ). Instead, stop
+ * after we find the first \0\0.
+ *
+ * (Found by Hilko Bengen in a fresh Windows XP SOFTWARE hive).
+ */
+ size_t slen = utf16_string_len_in_bytes_max (data, len);
+ if (slen < len)
+ len = slen;
+
char *ret = windows_utf16_to_utf8 (data, len);
free (data);
if (ret == NULL)
}
/* Get the length of a UTF-16 format string. Handle the string as
- * pairs of bytes, looking for the first \0\0 pair.
+ * pairs of bytes, looking for the first \0\0 pair. Only read up to
+ * 'len' maximum bytes.
*/
static size_t
-utf16_string_len_in_bytes (const char *str)
+utf16_string_len_in_bytes_max (const char *str, size_t len)
{
size_t ret = 0;
- while (str[0] || str[1]) {
+ while (len >= 2 && (str[0] || str[1])) {
str += 2;
ret += 2;
+ len -= 2;
}
return ret;
char *p = data;
size_t plen;
- while (p < data + len && (plen = utf16_string_len_in_bytes (p)) > 0) {
+ while (p < data + len &&
+ (plen = utf16_string_len_in_bytes_max (p, data + len - p)) > 0) {
nr_strings++;
char **ret2 = realloc (ret, (1 + nr_strings) * sizeof (char *));
if (ret2 == NULL) {