From b71b88f588f8660935a7d462e97b84aa2d669249 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Mon, 12 Jul 2010 15:06:35 +0100 Subject: [PATCH] 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. --- lib/hivex.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) 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) -- 1.8.3.1