diff -urpN john-1.7.8-jumbo-6-rc2/src/md5_gen.h john-1.7.8-jumbo-6b/src/md5_gen.h
--- john-1.7.8-jumbo-6-rc2/src/md5_gen.h	2011-08-03 15:04:25.000000000 +0000
+++ john-1.7.8-jumbo-6b/src/md5_gen.h	2011-09-20 16:28:18.218750000 +0000
@@ -33,8 +33,8 @@ typedef struct MD5_GEN_Constants_t
 #define MGF_NOTSSE2Safe              0x00000001
 #define MGF_ColonNOTValid            0x00000002
 #define MGF_SALTED                   0x00000004
-#define MGF_SALTED2                  0x00000008
-#define MGF_USERNAME                 0x00000010
+#define MGF_SALTED2                 (0x00000008|MGF_SALTED)
+#define MGF_USERNAME                (0x00000010|MGF_SALTED)
 #define MGF_USERNAME_UPCASE         (0x00000020|MGF_USERNAME)
 #define MGF_USERNAME_LOCASE         (0x00000040|MGF_USERNAME)
 #define MGF_INPBASE64		         0x00000080
@@ -42,19 +42,20 @@ typedef struct MD5_GEN_Constants_t
 #define MGF_INPBASE64_4x6			 0x00000200
 #define MGF_StartInX86Mode           0x00000400
 #define MGF_SALT_AS_HEX_TO_SALT2    (0x00000800|MGF_SALTED)
-#define MGF_SALT_UNICODE_B4_CRYPT    0x00001000
+#define MGF_SALT_UNICODE_B4_CRYPT   (0x00001000|MGF_SALTED)
 #define MGF_BASE_16_OUTPUT_UPCASE    0x00002000
 #define MGF_HDAA_SALT               (0x00004000|MGF_SALTED)
-#define MGF_FLD0                     0x00008000
-#define MGF_FLD1                     0x00010000
-#define MGF_FLD2                     0x00020000
-#define MGF_FLD3                     0x00040000
-#define MGF_FLD4                     0x00080000
-#define MGF_FLD5                     0x00100000
-#define MGF_FLD6                     0x00200000
-#define MGF_FLD7                     0x00400000
-#define MGF_FLD8                     0x00800000
-#define MGF_FLD9                     0x01000000
+#define MGF_FLDx_BIT                 0x00008000
+#define MGF_FLD0                    (0x00008000|MGF_SALTED)
+#define MGF_FLD1                    (0x00010000|MGF_SALTED)
+#define MGF_FLD2                    (0x00020000|MGF_SALTED)
+#define MGF_FLD3                    (0x00040000|MGF_SALTED)
+#define MGF_FLD4                    (0x00080000|MGF_SALTED)
+#define MGF_FLD5                    (0x00100000|MGF_SALTED)
+#define MGF_FLD6                    (0x00200000|MGF_SALTED)
+#define MGF_FLD7                    (0x00400000|MGF_SALTED)
+#define MGF_FLD8                    (0x00800000|MGF_SALTED)
+#define MGF_FLD9                    (0x01000000|MGF_SALTED)
 #define MGF_SHA1_40_BYTE_FINISH      0x02000000
 #define MGF_INPBASE64a               0x04000000
 #define MGF_UTF8                     0x08000000
diff -urpN john-1.7.8-jumbo-6-rc2/src/md5_gen_fmt.c john-1.7.8-jumbo-6b/src/md5_gen_fmt.c
--- john-1.7.8-jumbo-6-rc2/src/md5_gen_fmt.c	2011-09-20 16:47:13.781250000 +0000
+++ john-1.7.8-jumbo-6b/src/md5_gen_fmt.c	2011-09-20 16:52:39.640625000 +0000
@@ -673,7 +673,7 @@ static int valid(char *ciphertext, struc
 	for (i = 0; i < 10; ++i) {
 		char Fld[5];
 		sprintf(Fld, "$$F%d", i);
-		if ( (pPriv->FldMask & (MGF_FLD0<<i)) == (MGF_FLD0<<i) && !strstr(&ciphertext[pPriv->md5_gen_SALT_OFFSET-1], Fld))
+		if ( (pPriv->FldMask & (MGF_FLDx_BIT<<i)) == (MGF_FLDx_BIT<<i) && !strstr(&ciphertext[pPriv->md5_gen_SALT_OFFSET-1], Fld))
 			return 0;
 	}
 
@@ -697,8 +697,10 @@ static char *prepare(char *split_fields[
 	if (!pPriv)
 		return split_fields[1];
 
-	if (pFmt->params.salt_size && !strchr(split_fields[1], '$'))
-		return split_fields[1];
+	if (pFmt->params.salt_size && !strchr(split_fields[1], '$')) {
+		if (!pPriv->nUserName && !pPriv->FldMask)
+			return split_fields[1];
+	}
 
 	cpBuilding = FixupIfNeeded(cpBuilding, pPriv);
 	if (strncmp(cpBuilding, "md5_gen(", 8))
@@ -717,7 +719,7 @@ static char *prepare(char *split_fields[
 	}
 	for (i = 0; i <= 8; ++i) {
 		sprintf(Tmp, "$$F%d", i);
-		if ( split_fields[i] &&  (pPriv->FldMask&(MGF_FLD0<<i)) && !strstr(cpBuilding, Tmp)) {
+		if ( split_fields[i] &&  (pPriv->FldMask&(MGF_FLDx_BIT<<i)) && !strstr(cpBuilding, Tmp)) {
 			cpTmp = mem_alloc_tiny(strlen(cpBuilding) + 1 + 4 + strlen(split_fields[i]), MEM_ALIGN_NONE);
 			sprintf (cpTmp, "%s$$F%d%s", cpBuilding, i, split_fields[i]);
 			cpBuilding = cpTmp;
@@ -750,7 +752,10 @@ static void init(struct fmt_main *pFmt)
 	fmt_MD5gen.params.algorithm_name     = pFmt->params.algorithm_name;
 	fmt_MD5gen.params.benchmark_comment  = pFmt->params.benchmark_comment;
 	fmt_MD5gen.params.benchmark_length   = pFmt->params.benchmark_length;
-	fmt_MD5gen.params.plaintext_length   = pFmt->params.plaintext_length;
+	if ( (pFmt->params.flags&FMT_UNICODE) && options.utf8 )
+		pFmt->params.plaintext_length = pFmt->params.plaintext_length * 3; // we allow for 3 bytes of utf8 data to make up the number of plaintext_length unicode chars.
+	else
+		fmt_MD5gen.params.plaintext_length   = pFmt->params.plaintext_length;
 	fmt_MD5gen.params.salt_size          = pFmt->params.salt_size;
 	if (pFmt->params.salt_size > 0)
 		++pFmt->params.salt_size;
@@ -2921,7 +2926,10 @@ void MD5GenBaseFunc__append_keys()
 				if (!options.ascii && !options.iso8859_1) {
 					UTF16 utf16Str[27+1]; // 27 chars is 'max' that fits in SSE without overflow, so that is where we limit it at now
 					int outlen;
-					outlen = enc_to_utf16(utf16Str, 27, (unsigned char*)saved_key[j], saved_key_len[j]) * sizeof(UTF16);
+					int maxlen=27;
+					if (curdat.pSetup->MaxInputLen < maxlen)
+						maxlen = curdat.pSetup->MaxInputLen;
+					outlen = enc_to_utf16(utf16Str, maxlen, (unsigned char*)saved_key[j], saved_key_len[j]) * sizeof(UTF16);
 					if (outlen <= 0)
 						outlen = strlen16(utf16Str) * sizeof(UTF16);
 					total_len[idx] += ( outlen << ((32/MMX_COEF)*idx_mod));
@@ -3006,7 +3014,10 @@ void MD5GenBaseFunc__append_keys2()
 				if (!options.ascii && !options.iso8859_1) {
 					UTF16 utf16Str[27+1]; // 27 chars is 'max' that fits in SSE without overflow, so that is where we limit it at now
 					int outlen;
-					outlen = enc_to_utf16(utf16Str, 27, (unsigned char*)saved_key[j], saved_key_len[j]) * sizeof(UTF16);
+					int maxlen=27;
+					if (curdat.pSetup->MaxInputLen < maxlen)
+						maxlen = curdat.pSetup->MaxInputLen;
+					outlen = enc_to_utf16(utf16Str, maxlen, (unsigned char*)saved_key[j], saved_key_len[j]) * sizeof(UTF16);
 					if (outlen <= 0)
 						outlen = strlen16(utf16Str) * sizeof(UTF16);
 					total_len2[idx] += ( outlen << ((32/MMX_COEF)*idx_mod));
diff -urpN john-1.7.8-jumbo-6-rc2/src/md5_gen_preloads.c john-1.7.8-jumbo-6b/src/md5_gen_preloads.c
--- john-1.7.8-jumbo-6-rc2/src/md5_gen_preloads.c	2011-08-03 15:04:25.000000000 +0000
+++ john-1.7.8-jumbo-6b/src/md5_gen_preloads.c	2011-09-19 20:52:29.921875000 +0000
@@ -794,7 +794,11 @@ static MD5_GEN_Setup Setups[] =
 	{ " md5_gen(26): sha1($p) raw-sha1",            _Funcs_26,_Preloads_26,_ConstDefault, MGF_SHA1_40_BYTE_FINISH, MGF_RAW_SHA1_INPUT },
 	{ " md5_gen(27): FreeBSD MD5",                  _Funcs_27,_Preloads_27,_Const_27,     MGF_SALTED|MGF_INPBASE64a|MGF_StartInX86Mode, MGF_FreeBSDMD5Setup, 0, 15 },
 	{ " md5_gen(28): Apache MD5",                   _Funcs_28,_Preloads_28,_Const_28,     MGF_SALTED|MGF_INPBASE64a|MGF_StartInX86Mode, MGF_FreeBSDMD5Setup, 0, 15 },
-	{ " md5_gen(29): md5(unicode($p))",             _Funcs_29,_Preloads_29,_ConstDefault, MGF_UTF8, MGF_NO_FLAG, 0, 27*3 } // 27 unicode chars is 'max' we can do.
+#if defined (MMX_COEF)
+	{ " md5_gen(29): md5(unicode($p))",             _Funcs_29,_Preloads_29,_ConstDefault, MGF_UTF8, MGF_NO_FLAG, 0, 27 } // if we are in utf8 mode, we triple this in the init() call
+#else
+	{ " md5_gen(29): md5(unicode($p))",             _Funcs_29,_Preloads_29,_ConstDefault, MGF_UTF8, MGF_NO_FLAG, 0, 50 } // if we are in utf8 mode, we triple this in the init() call
+#endif
 };
 
 char *md5_gen_PRELOAD_SIGNATURE(int cnt)
diff -urpN john-1.7.8-jumbo-6-rc2/src/rawmd5u_fmt_plug.c john-1.7.8-jumbo-6b/src/rawmd5u_fmt_plug.c
--- john-1.7.8-jumbo-6-rc2/src/rawmd5u_fmt_plug.c	2011-09-20 16:45:09.203125000 +0000
+++ john-1.7.8-jumbo-6b/src/rawmd5u_fmt_plug.c	2011-09-19 20:52:29.859375000 +0000
@@ -35,7 +35,7 @@
 #define BENCHMARK_COMMENT		""
 #define BENCHMARK_LENGTH		-1
 
-#define PLAINTEXT_LENGTH		54 // octets, not characters. Trimmed in init()
+#define PLAINTEXT_LENGTH		54 // octets, not characters. Trimmed in init(),  now 'trimmed' in the md5_gen and we harvest the actual length from that format.
 #define CIPHERTEXT_LENGTH		32
 #define BINARY_SIZE				16
 #define SALT_SIZE				0
@@ -111,8 +111,6 @@ struct fmt_main fmt_rawmd5u =
 static void rawmd5u_init(struct fmt_main *pFmt)
 {
 	if (options.utf8) {
-		// We may need three octets of input to produce two octets of key
-		fmt_rawmd5u.params.plaintext_length = PLAINTEXT_LENGTH / 2 * 3;
 		rawmd5u_tests[1].ciphertext = "94a4e171de16580742c4d141e6607bf7";
 		rawmd5u_tests[1].plaintext = "\xE2\x82\xAC";	// Euro sign
 		rawmd5u_tests[2].ciphertext = "03c60810f0e54d16e826aca385d776c8";
@@ -122,8 +120,6 @@ static void rawmd5u_init(struct fmt_main
 		rawmd5u_tests[4].ciphertext = "8007d9070b27db7b30433df2cd10abc1";
 		rawmd5u_tests[4].plaintext = "\xC3\xBC\xE2\x82\xAC";	// u-umlaut and euro
 	} else {
-		// We need one octet of input to produce two octets of key
-		fmt_rawmd5u.params.plaintext_length = PLAINTEXT_LENGTH / 2;
 		if (CP_to_Unicode[0xfc] == 0x00fc) {
 			rawmd5u_tests[1].ciphertext = "ea7ab2b5c07650badab30790d0c9b63e";
 			rawmd5u_tests[1].plaintext = "\xFC";	// German u-umlaut in iso-8859-1
@@ -140,6 +136,7 @@ static void rawmd5u_init(struct fmt_main
 		fmt_rawmd5u.methods.binary = our_binary;
 		fmt_rawmd5u.methods.salt = our_salt;
 		fmt_rawmd5u.params.algorithm_name = pFmt_MD5_gen_29->params.algorithm_name;
+		fmt_rawmd5u.params.plaintext_length = pFmt_MD5_gen_29->params.plaintext_length;
 		pFmt->private.initialized = 1;
 	}
 }
