summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Jones <rjones@redhat.com>2010-07-12 15:06:35 +0100
committerRichard Jones <rjones@redhat.com>2010-07-12 15:07:12 +0100
commitb71b88f588f8660935a7d462e97b84aa2d669249 (patch)
tree85d0f2f0f48583e530e9858d1fcaacd840e1368e
parent374659033e8eeea5b25246a9ef80bee3ebc2cde9 (diff)
downloadhivex-b71b88f588f8660935a7d462e97b84aa2d669249.tar.gz
hivex-b71b88f588f8660935a7d462e97b84aa2d669249.tar.xz
hivex-b71b88f588f8660935a7d462e97b84aa2d669249.zip
Don't try to process junk after a string value as UTF-16.
Thanks to Hilko Bengen for characterizing the issue and providing an initial version of this patch.
-rw-r--r--lib/hivex.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/lib/hivex.c b/lib/hivex.c
index 2b22924..13d7556 100644
--- a/lib/hivex.c
+++ b/lib/hivex.c
@@ -62,6 +62,8 @@
#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 (const char *str);
+static size_t utf16_string_len_in_bytes_max (const char *str, size_t len);
struct hive_h {
char *filename;
@@ -1319,6 +1321,20 @@ hivex_value_string (hive_h *h, hive_value_h value)
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)
@@ -1355,6 +1371,21 @@ utf16_string_len_in_bytes (const char *str)
return ret;
}
+/* As for utf16_string_len_in_bytes but only read up to a maximum length. */
+static size_t
+utf16_string_len_in_bytes_max (const char *str, size_t len)
+{
+ size_t ret = 0;
+
+ while (len > 0 && (str[0] || str[1])) {
+ str += 2;
+ ret += 2;
+ len -= 2;
+ }
+
+ return ret;
+}
+
/* http://blogs.msdn.com/oldnewthing/archive/2009/10/08/9904646.aspx */
char **
hivex_value_multiple_strings (hive_h *h, hive_value_h value)