diff -urpN john-1.7.8-jumbo-5a/src/DMD5_fmt_plug.c john-1.7.8-jumbo-5b/src/DMD5_fmt_plug.c
--- john-1.7.8-jumbo-5a/src/DMD5_fmt_plug.c	2011-08-20 16:36:51.078125000 +0000
+++ john-1.7.8-jumbo-5b/src/DMD5_fmt_plug.c	2011-08-19 00:01:48.000000000 +0000
@@ -112,12 +112,12 @@ static struct fmt_tests tests[] = {
 
 static int dmd5_valid(char *ciphertext, struct fmt_main *pFmt)
 {
-	if (strncmp(ciphertext, "$DIGEST-MD5$", 12) != 0)
-		return 0;
-
 	unsigned char *c = (unsigned char *)ciphertext + 12;
 	unsigned char f = 0;
 
+	if (strncmp(ciphertext, "$DIGEST-MD5$", 12) != 0)
+		return 0;
+
 	while(*c)
 		if (*c++ == '$')
 			f++;
diff -urpN john-1.7.8-jumbo-5a/src/john.c john-1.7.8-jumbo-5b/src/john.c
--- john-1.7.8-jumbo-5a/src/john.c	2011-08-20 16:37:35.078125000 +0000
+++ john-1.7.8-jumbo-5b/src/john.c	2011-08-19 04:00:30.000000000 +0000
@@ -93,8 +93,8 @@ extern int undrop(int argc, char **argv)
 extern int ssh2john(int argc, char **argv);
 extern int pdf2john(int argc, char **argv);
 extern int rar2john(int argc, char **argv);
-extern int zip2john(int argc, char **argv);
 #endif
+extern int zip2john(int argc, char **argv);
 
 static struct db_main database;
 static struct fmt_main dummy_format;
diff -urpN john-1.7.8-jumbo-5a/src/misc.c john-1.7.8-jumbo-5b/src/misc.c
--- john-1.7.8-jumbo-5a/src/misc.c	2011-05-25 16:37:35.000000000 +0000
+++ john-1.7.8-jumbo-5b/src/misc.c	2011-08-19 03:57:34.000000000 +0000
@@ -56,7 +56,7 @@ void pexit(char *format, ...)
 	error();
 }
 
-int write_loop(int fd, char *buffer, int count)
+int write_loop(int fd, const char *buffer, int count)
 {
 	int offset, block;
 
@@ -103,9 +103,10 @@ char *fgetl(char *s, int size, FILE *str
 	return res;
 }
 
-char *strnfcpy(char *dst, char *src, int size)
+char *strnfcpy(char *dst, const char *src, int size)
 {
-	char *dptr = dst, *sptr = src;
+	char *dptr = dst;
+	const char *sptr = src;
 	int count = size;
 
 	while (count--)
@@ -114,9 +115,10 @@ char *strnfcpy(char *dst, char *src, int
 	return dst;
 }
 
-char *strnzcpy(char *dst, char *src, int size)
+char *strnzcpy(char *dst, const char *src, int size)
 {
-	char *dptr = dst, *sptr = src;
+	char *dptr = dst;
+	const char *sptr = src;
 	int count = size;
 
 	if (count)
@@ -127,9 +129,10 @@ char *strnzcpy(char *dst, char *src, int
 	return dst;
 }
 
-char *strnzcat(char *dst, char *src, int size)
+char *strnzcat(char *dst, const char *src, int size)
 {
-	char *dptr = dst, *sptr = src;
+	char *dptr = dst;
+	const char *sptr = src;
 	int count = size;
 
 	if (count) {
diff -urpN john-1.7.8-jumbo-5a/src/misc.h john-1.7.8-jumbo-5b/src/misc.h
--- john-1.7.8-jumbo-5a/src/misc.h	2011-08-20 16:35:03.406250000 +0000
+++ john-1.7.8-jumbo-5b/src/misc.h	2011-08-19 03:57:34.000000000 +0000
@@ -34,7 +34,7 @@ extern void pexit(char *format, ...)
  * Attempts to write all the supplied data. Returns the number of bytes
  * written, or -1 on error.
  */
-extern int write_loop(int fd, char *buffer, int count);
+extern int write_loop(int fd, const char *buffer, int count);
 
 /*
  * Similar to fgets(), but doesn't leave the newline character in the buffer,
@@ -47,18 +47,18 @@ extern char *fgetl(char *s, int size, FI
  * Similar to strncpy(), but terminates with only one NUL if there's room
  * instead of padding to the supplied size like strncpy() does.
  */
-extern char *strnfcpy(char *dst, char *src, int size);
+extern char *strnfcpy(char *dst, const char *src, int size);
 
 /*
  * Similar to the above, but always NUL terminates the string.
  */
-extern char *strnzcpy(char *dst, char *src, int size);
+extern char *strnzcpy(char *dst, const char *src, int size);
 
 /*
  * Similar to strncat(), but total buffer size is supplied, and always NUL
  * terminates the string.
  */
-extern char *strnzcat(char *dst, char *src, int size);
+extern char *strnzcat(char *dst, const char *src, int size);
 
 /*
  * Converts a string to lowercase.
diff -urpN john-1.7.8-jumbo-5a/src/pdf_fmt.c john-1.7.8-jumbo-5b/src/pdf_fmt.c
--- john-1.7.8-jumbo-5a/src/pdf_fmt.c	2011-08-20 16:34:59.906250000 +0000
+++ john-1.7.8-jumbo-5b/src/pdf_fmt.c	2011-08-19 04:04:31.000000000 +0000
@@ -27,21 +27,25 @@
  * TODO: add support for detecting AESV2 and AESV3 encrypted documents
  * lacking "trailer dictionary" to pdfparser.c */
 
-#include <string.h>
-#include "arch.h"
-#include "params.h"
-#include "common.h"
-#include "formats.h"
-
 #include <openssl/ssl.h>
 #include <openssl/bio.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
 
+#undef MEM_FREE
+
+#include <string.h>
+#include "arch.h"
+
 #include "pdfcrack.h"
 #include "pdfparser.h"
 
+#include "params.h"
+#include "common.h"
+#include "formats.h"
+#include "misc.h"
+
 #define FORMAT_LABEL        "pdf"
 #define FORMAT_NAME         "pdf"
 #define ALGORITHM_NAME      "32/" ARCH_BITS_STR
diff -urpN john-1.7.8-jumbo-5a/src/rar_fmt.c john-1.7.8-jumbo-5b/src/rar_fmt.c
--- john-1.7.8-jumbo-5a/src/rar_fmt.c	2011-08-20 16:34:59.937500000 +0000
+++ john-1.7.8-jumbo-5b/src/rar_fmt.c	2011-08-19 04:06:19.000000000 +0000
@@ -20,18 +20,21 @@
  * rar -p mode support is based on rar's technote.txt documentation and is
  * currently incomplete. */
 
+#include <openssl/aes.h>
+#include <openssl/sha.h>
+#include <openssl/ssl.h>
+
+#undef MEM_FREE
+
 #include <string.h>
 #include <assert.h>
 #include <errno.h>
 #include "arch.h"
 #include "crc32.h"
 #include "misc.h"
-#include "params.h"
 #include "common.h"
 #include "formats.h"
-#include <openssl/aes.h>
-#include <openssl/sha.h>
-#include <openssl/ssl.h>
+#include "params.h"
 
 #define FORMAT_LABEL        "rar"
 #define FORMAT_NAME         "rar"
diff -urpN john-1.7.8-jumbo-5a/src/rules.c john-1.7.8-jumbo-5b/src/rules.c
--- john-1.7.8-jumbo-5a/src/rules.c	2011-08-20 16:37:14.578125000 +0000
+++ john-1.7.8-jumbo-5b/src/rules.c	2011-08-20 13:16:52.000000000 +0000
@@ -651,9 +651,10 @@ accept:
 	return out_rule;
 }
 
-char *rules_apply(char *word, char *rule, int split, char *last)
+char *rules_apply(const char *word, char *rule, int split, char *last)
 {
-	char *in, *alt, *memory = word;
+	char *in, *alt;
+	const char *memory = word;
 	int length;
 	int which;
 
@@ -1122,7 +1123,8 @@ char *rules_apply(char *word, char *rule
 			break;
 
 		case 'M':
-			strnfcpy(memory = memory_buffer, in, rules_max_length);
+			memory = memory_buffer;
+			strnfcpy(memory_buffer, in, rules_max_length);
 			rules_vars['m'] = (unsigned char)length - 1;
 			break;
 
@@ -1134,7 +1136,8 @@ char *rules_apply(char *word, char *rule
 		case 'X': /* append/insert/prepend substring from memory */
 			{
 				int mpos, count, ipos, mleft;
-				char *inp, *mp;
+				char *inp;
+				const char *mp;
 				POSITION(mpos)
 				POSITION(count)
 				POSITION(ipos)
diff -urpN john-1.7.8-jumbo-5a/src/rules.h john-1.7.8-jumbo-5b/src/rules.h
--- john-1.7.8-jumbo-5a/src/rules.h	2009-12-28 19:28:21.000000000 +0000
+++ john-1.7.8-jumbo-5b/src/rules.h	2011-08-19 03:47:46.000000000 +0000
@@ -73,7 +73,7 @@ extern char *rules_reject(char *rule, in
  * rules_apply() are properly aligned).  If the new mangled word matches the
  * previous one, it will be rejected (rules_apply() will return NULL).
  */
-extern char *rules_apply(char *word, char *rule, int split, char *last);
+extern char *rules_apply(const char *word, char *rule, int split, char *last);
 
 /*
  * Checks if all the rules for context are valid. Returns the number of rules,
diff -urpN john-1.7.8-jumbo-5a/src/ssh_fmt.c john-1.7.8-jumbo-5b/src/ssh_fmt.c
--- john-1.7.8-jumbo-5a/src/ssh_fmt.c	2011-08-20 16:34:59.937500000 +0000
+++ john-1.7.8-jumbo-5b/src/ssh_fmt.c	2011-08-19 04:04:06.000000000 +0000
@@ -9,12 +9,6 @@
  * This patch is inspired by the ssh-privkey-crack program.
  * http://neophob.com/2007/10/ssh-private-key-cracker/ */
 
-#include <string.h>
-#include "arch.h"
-#include "params.h"
-#include "common.h"
-#include "formats.h"
-
 /* PEM_read_bio_PrivateKey and related OpenSSL functions are too high
  * level for brute-forcing purposes. So we drill down and find suitable
  * low-level OpenSSL functions.*/
@@ -28,6 +22,16 @@
 #include <openssl/pem.h>
 #include <openssl/err.h>
 
+#include <string.h>
+#include "arch.h"
+
+#undef MEM_FREE
+
+#include "common.h"
+#include "formats.h"
+#include "params.h"
+#include "misc.h"
+
 #define FORMAT_LABEL        "ssh"
 #define FORMAT_NAME         "ssh"
 #define ALGORITHM_NAME      "32/" ARCH_BITS_STR
diff -urpN john-1.7.8-jumbo-5a/src/wordlist.c john-1.7.8-jumbo-5b/src/wordlist.c
--- john-1.7.8-jumbo-5a/src/wordlist.c	2011-08-20 16:37:24.578125000 +0000
+++ john-1.7.8-jumbo-5b/src/wordlist.c	2011-08-20 17:16:49.000000000 +0000
@@ -195,17 +195,9 @@ static int get_progress(int *hundth_perc
 	return percent;
 }
 
-static char *dummy_rules_apply(char *word, char *rule, int split, char *last)
+static char *dummy_rules_apply(const char *word, char *rule, int split, char *last)
 {
-	if (nWordFileLines)
-		// Dupes are already ditched, truncation already done
-		// and we just copy the pointer
-		return (last = word);
-
-	word[length] = 0;
-	if (strcmp(word, last))
-		return strcpy(last, word);
-	return NULL;
+	return (char*)word;
 }
 
 void do_wordlist_crack(struct db_main *db, char *name, int rules)
@@ -214,12 +206,13 @@ void do_wordlist_crack(struct db_main *d
 		char buffer[2][LINE_BUFFER_SIZE + CACHE_BANK_SHIFT];
 		ARCH_WORD dummy;
 	} aligned;
-	char *line = aligned.buffer[0], *last = aligned.buffer[1];
+	const char *line = aligned.buffer[0];
+	char *last = aligned.buffer[1];
 	struct rpp_context ctx;
 	char *prerule, *rule, *word;
-	char *(*apply)(char *word, char *rule, int split, char *last);
+	char *(*apply)(const char *word, char *rule, int split, char *last);
 	long file_len;
-	int i, pipe_input=0, max_pipe_words=0, rules_keep=0, init_this_time=1;
+	int i, pipe_input=0, max_pipe_words=0, rules_keep=0, init_this_time=1, really_done=0;
 	char msg_buf[128];
 
 #ifdef HAVE_MPI
@@ -279,7 +272,7 @@ void do_wordlist_crack(struct db_main *d
 				fseek(word_file, 0, SEEK_SET);
 
 				// Now copy just our share to memory
-				word_file_str = mem_alloc(my_size + 1);
+				word_file_str = mem_alloc(my_size + LINE_BUFFER_SIZE + 1);
 				i = 0;
 				for (myWordFileLines = 0;; ++myWordFileLines) {
 					if (!fgets(file_line, sizeof(file_line), word_file)) {
@@ -309,7 +302,7 @@ void do_wordlist_crack(struct db_main *d
 				          name, file_len, db->options->max_wordfile_memory);
 				if (mpi_p > 1 && mpi_id == 0)
 					fprintf(stderr,"MPI: each node loaded the whole wordfile to memory\n");
-				word_file_str = mem_alloc(file_len + 1);
+				word_file_str = mem_alloc(file_len + LINE_BUFFER_SIZE + 1);
 				if (fread(word_file_str, 1, file_len, word_file) != file_len) {
 					if (ferror(word_file))
 						pexit("fread");
@@ -326,7 +319,7 @@ void do_wordlist_crack(struct db_main *d
 			/* probably should only be debug message, but I left it in */
 			log_event("loading wordfile %s into memory (%lu bytes, max_size=%u)\n", name, file_len, db->options->max_wordfile_memory);
 
-			word_file_str = mem_alloc(file_len+1);
+			word_file_str = mem_alloc(file_len + LINE_BUFFER_SIZE + 1);
 			if (fread(word_file_str, 1, file_len, word_file) != file_len) {
 				if (ferror(word_file))
 					pexit("fread");
@@ -345,7 +338,7 @@ void do_wordlist_crack(struct db_main *d
 			}
 			for (nWordFileLines = 1; cp; ++nWordFileLines)
 				cp = memchr(&cp[1], csearch, file_len - (cp - word_file_str) - 1);
-			words = mem_alloc(nWordFileLines * sizeof(char*));
+			words = mem_alloc( (nWordFileLines+1) * sizeof(char*));
 			log_event("wordfile had %u lines and required %lu bytes for index.\n", nWordFileLines, (unsigned long)(nWordFileLines * sizeof(char*)));
 
 			i = 0;
@@ -356,13 +349,23 @@ void do_wordlist_crack(struct db_main *d
 				while ((ep < aep) && *ep && *ep != '\n' && *ep != '\r') ep++;
 				ec = *ep;
 				*ep = 0;
-				if (ep - cp > length)
-					cp[length] = 0;
-				if ((strncmp(cp, "#!comment", 9)) &&
-				    (!i || strcmp(cp, words[i-1])))
-					words[i++] = cp;
-				if (i == nWordFileLines)
-					break;
+				if (strncmp(cp, "#!comment", 9)) {
+					if (!rules) {
+						if (ep - cp >= length)
+							cp[length] = 0;
+						if (!i || strcmp(cp, words[i-1])) {
+							words[i++] = cp;
+							if (i == nWordFileLines)
+								break;
+						}
+					} else {
+						if (ep - cp >= LINE_BUFFER_SIZE)
+							cp[LINE_BUFFER_SIZE-1] = 0;
+						words[i++] = cp;
+						if (i == nWordFileLines)
+							break;
+					}
+				}
 				cp = ep + 1;
 				if (ec == '\r' && *cp == '\n') cp++;
 			} while (cp < aep);
@@ -384,7 +387,10 @@ void do_wordlist_crack(struct db_main *d
 			pipe_input = 1;
 			if (db->options->max_wordfile_memory < 0x20000)
 				db->options->max_wordfile_memory = 0x20000;
-			max_pipe_words = (db->options->max_wordfile_memory/16);
+			if (length < 16)
+				max_pipe_words = (db->options->max_wordfile_memory/length);
+			else
+				max_pipe_words = (db->options->max_wordfile_memory/16);
 
 			word_file_str = mem_alloc(db->options->max_wordfile_memory);
 			words = mem_alloc(max_pipe_words * sizeof(char*));
@@ -403,19 +409,27 @@ GRAB_NEXT_PIPE_LOAD:;
 				rules = rules_keep;
 				nWordFileLines = 0;
 				cpi = word_file_str;
-				cpe = (cpi + db->options->max_wordfile_memory) - LINE_BUFFER_SIZE;
+				cpe = (cpi + db->options->max_wordfile_memory) - (LINE_BUFFER_SIZE+1);
 				while (nWordFileLines < max_pipe_words) {
-					if (!fgetl(cpi, length+3, word_file)) {
+					if (!fgetl(cpi, LINE_BUFFER_SIZE, word_file)) {
 						pipe_input = 0; /* We are now done.  After processing, do NOT goto the GRAB_NEXT... again */
 						break;
 					}
-					cpi[length] = 0;
-					if ((strncmp(cpi, "#!comment", 9)) &&
-						(!(cpi != word_file_str) || strcmp(cpi, words[nWordFileLines-1]))) {
-						words[nWordFileLines++] = cpi;
-						cpi += (strlen(cpi)+1);
-						if (cpi > cpe)
-							break;
+					if (strncmp(cpi, "#!comment", 9)) {
+						if (!rules) {
+							cpi[length] = 0;
+							if (!nWordFileLines || strcmp(cpi, words[nWordFileLines-1])) {
+								words[nWordFileLines++] = cpi;
+								cpi += (strlen(cpi)+1);
+								if (cpi > cpe)
+									break;
+							}
+						} else {
+							words[nWordFileLines++] = cpi;
+							cpi += (strlen(cpi)+1);
+							if (cpi > cpe)
+								break;
+						}
 					}
 				}
 				sprintf(msg_buf, "- Read block of %d candidate passwords from pipe", nWordFileLines);
@@ -424,6 +438,8 @@ GRAB_NEXT_PIPE_LOAD:;
 		}
 	}
 
+	length = db->format->params.plaintext_length;
+
 	if (rules) {
 		if (rpp_init(rule_ctx = &ctx, db->options->activewordlistrules)) {
 			log_event("! No wordlist mode rules found");
@@ -542,14 +558,18 @@ GRAB_NEXT_PIPE_LOAD:;
 				if (!distributeWords || line_number % mpi_p == mpi_id)
 #endif
 #if ARCH_ALLOWS_UNALIGNED
-					line = words[nCurLine++];
+				line = words[nCurLine++];
 #else
-					strcpy(line, words[nCurLine++]);
+				strcpy(line, words[nCurLine++]);
 #endif
 			}
 			else {
-				if (!fgetl(line, LINE_BUFFER_SIZE, word_file))
-					break;
+				do {
+					if (!fgetl(((char*)line), LINE_BUFFER_SIZE, word_file))
+						break;
+				} while (strncmp(line, "#!comment", 9));
+				if (!rules)
+					((char*)line)[length] = 0;
 			}
 #ifdef HAVE_MPI
 			// MPI distribution - leapfrog words
@@ -559,22 +579,16 @@ GRAB_NEXT_PIPE_LOAD:;
 			line_number++;
 #endif
 
-			if (line[0] != '#') {
-not_comment:
-				if ((word = apply(line, rule, -1, last))) {
-					last = word;
-
-					if (ext_filter(word))
-					if (crk_process_key(word)) {
-						rules = 0;
-						break;
-					}
+			if ((word = apply(line, rule, -1, last))) {
+				last = word;
+
+				if (ext_filter(word))
+				if (crk_process_key(word)) {
+					rules = 0;
+					really_done=1; /* keep us from relooping, if in -pipe mode */
+					break;
 				}
-				continue;
 			}
-
-			if (strncmp(line, "#!comment", 9))
-				goto not_comment;
 		}
 
 		if (rules) {
@@ -591,7 +605,7 @@ not_comment:
 		}
 	} while (rules);
 
-	if (pipe_input)
+	if (pipe_input && !really_done)
 		goto GRAB_NEXT_PIPE_LOAD;
 
 	crk_done();
