From b05e218f9114f13e3f8c551b7547edca505a4611 Mon Sep 17 00:00:00 2001
From: rswindell <>
Date: Mon, 8 Jul 2019 07:08:01 +0000
Subject: [PATCH] Pass a new "is_utf8" argument to wordwrap() rather than
 auto-detect UTF-8 text. This means the JS global word_wrap() method has a new
 optional Boolean arg as well.

---
 src/sbbs3/js_global.c  |  9 ++++++---
 src/sbbs3/putmsg.cpp   |  3 ++-
 src/sbbs3/wordwrap.c   |  7 +------
 src/sbbs3/wordwrap.h   |  2 +-
 src/sbbs3/writemsg.cpp | 19 ++++++++++++-------
 5 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c
index c30155c6b9..44ad9b7e66 100644
--- a/src/sbbs3/js_global.c
+++ b/src/sbbs3/js_global.c
@@ -1179,6 +1179,7 @@ js_word_wrap(JSContext *cx, uintN argc, jsval *arglist)
 	int32		len=79;
 	int32		oldlen=79;
 	JSBool		handle_quotes=JS_TRUE;
+	JSBool		is_utf8=JS_FALSE;
 	char*		inbuf = NULL;
 	char*		outbuf;
 	JSString*	js_str;
@@ -1210,10 +1211,12 @@ js_word_wrap(JSContext *cx, uintN argc, jsval *arglist)
 
 	if(argc>3 && JSVAL_IS_BOOLEAN(argv[3]))
 		handle_quotes = JSVAL_TO_BOOLEAN(argv[3]);
+	if(argc>4 && JSVAL_IS_BOOLEAN(argv[4]))
+		is_utf8 = JSVAL_TO_BOOLEAN(argv[4]);
 
 	rc=JS_SUSPENDREQUEST(cx);
 
-	outbuf=wordwrap(inbuf, len, oldlen, handle_quotes);
+	outbuf=wordwrap(inbuf, len, oldlen, handle_quotes, is_utf8);
 	free(inbuf);
 
 	JS_RESUMEREQUEST(cx, rc);
@@ -4281,10 +4284,10 @@ static jsSyncMethodSpec js_global_functions[] = {
 	,JSDOCSTR("return a decoded HTML-encoded text string")
 	,311
 	},
-	{"word_wrap",		js_word_wrap,		1,	JSTYPE_STRING,	JSDOCSTR("text [,line_length=<tt>79</tt> [, orig_line_length=<tt>79</tt> [, handle_quotes=<tt>true</tt>]]]]")
+	{"word_wrap",		js_word_wrap,		1,	JSTYPE_STRING,	JSDOCSTR("text [,line_length=<tt>79</tt> [, orig_line_length=<tt>79</tt> [, handle_quotes=<tt>true</tt> [, is_utf8=<tt>false</tt>]]]]")
 	,JSDOCSTR("returns a word-wrapped version of the text string argument optionally handing quotes magically, "
 		"<i>line_length</i> defaults to <i>79</i>, <i>orig_line_length</i> defaults to <i>79</i>, "
-		"and <i>handle_quotes</i> defaults to <i>true</i>")
+		"<i>handle_quotes</i> defaults to <i>true</i>, and <i>is_utf8</i> defaults to <i>false</i>")
 	,311
 	},
 	{"quote_msg",		js_quote_msg,		1,	JSTYPE_STRING,	JSDOCSTR("text [,line_length=<tt>79</tt>] [,prefix=<tt>\" > \"</tt>]")
diff --git a/src/sbbs3/putmsg.cpp b/src/sbbs3/putmsg.cpp
index 5e9e00a297..5d77ce3aff 100644
--- a/src/sbbs3/putmsg.cpp
+++ b/src/sbbs3/putmsg.cpp
@@ -84,7 +84,8 @@ char sbbs_t::putmsg(const char *buf, long mode, long org_cols)
 		char *wrapped;
 		if(org_cols < TERM_COLS_MIN)
 			org_cols = TERM_COLS_DEFAULT;
-		if((wrapped=::wordwrap((char*)str+l, cols - 1, org_cols - 1, /* handle_quotes: */TRUE)) == NULL)
+		if((wrapped=::wordwrap((char*)str+l, cols - 1, org_cols - 1, /* handle_quotes: */TRUE
+			,/* is_utf8: */INT_TO_BOOL(mode&P_UTF8))) == NULL)
 			errormsg(WHERE,ERR_ALLOC,"wordwrap buffer",0);
 		else {
 			truncsp_lines(wrapped);
diff --git a/src/sbbs3/wordwrap.c b/src/sbbs3/wordwrap.c
index 0c2cd27938..f968336f5a 100644
--- a/src/sbbs3/wordwrap.c
+++ b/src/sbbs3/wordwrap.c
@@ -37,9 +37,6 @@
 #include "wordwrap.h"
 #include "utf8.h"
 
-/* sbbs.h: */
-extern BOOL str_is_ascii(const char*);
-
 struct prefix {
 	size_t cols;
 	char *bytes;
@@ -567,14 +564,12 @@ static char *wrap_paragraphs(struct paragraph *paragraph, size_t outlen, BOOL ha
 	return outbuf;
 }
 
-char* wordwrap(char* inbuf, int len, int oldlen, BOOL handle_quotes)
+char* wordwrap(char* inbuf, int len, int oldlen, BOOL handle_quotes, BOOL is_utf8)
 {
 	char*		outbuf;
 	struct paragraph *paragraphs;
 	BOOL		has_crs;
-	BOOL		is_utf8;
 
-	is_utf8 = (!str_is_ascii(inbuf) && utf8_str_is_valid(inbuf));
 	paragraphs = word_unwrap(inbuf, oldlen, handle_quotes, &has_crs, is_utf8);
 	if (paragraphs == NULL)
 		return NULL;
diff --git a/src/sbbs3/wordwrap.h b/src/sbbs3/wordwrap.h
index 2a7767c0a1..8b3ebbac7d 100644
--- a/src/sbbs3/wordwrap.h
+++ b/src/sbbs3/wordwrap.h
@@ -38,7 +38,7 @@
 extern "C" {
 #endif
 
-char* wordwrap(char* inbuf, int len, int oldlen, BOOL handle_quotes);
+char* wordwrap(char* inbuf, int len, int oldlen, BOOL handle_quotes, BOOL is_utf8);
 
 #ifdef __cplusplus
 }
diff --git a/src/sbbs3/writemsg.cpp b/src/sbbs3/writemsg.cpp
index 94b9a2c511..1d28cafde8 100644
--- a/src/sbbs3/writemsg.cpp
+++ b/src/sbbs3/writemsg.cpp
@@ -105,12 +105,17 @@ bool sbbs_t::quotemsg(smb_t* smb, smbmsg_t* msg, bool tails)
 	if((buf=smb_getmsgtxt(smb, msg, mode)) != NULL) {
 		strip_invalid_attr(buf);
 		truncsp(buf);
-		if(smb_msg_is_utf8(msg) && !term_supports(UTF8)) {
-			utf8_normalize_str(buf);
-			utf8_replace_chars(buf, unicode_to_cp437
-				,/* unsupported char: */'\xA8' /* Inverted question mark */
-				,/* unsupported zero-width ch: */0
-				,/* decode error char: */ '\xAD' /* inverted exclamation mark */);
+		BOOL is_utf8 = FALSE;
+		if(smb_msg_is_utf8(msg)) {
+			if(term_supports(UTF8))
+				is_utf8 = TRUE;
+			else {
+				utf8_normalize_str(buf);
+				utf8_replace_chars(buf, unicode_to_cp437
+					,/* unsupported char: */'\xA8' /* Inverted question mark */
+					,/* unsupported zero-width ch: */0
+					,/* decode error char: */ '\xAD' /* inverted exclamation mark */);
+			}
 		}
 		if(!useron_xedit || (useron_xedit && (cfg.xedit[useron_xedit-1]->misc&QUOTEWRAP))) {
 			int wrap_cols = 0;
@@ -118,7 +123,7 @@ bool sbbs_t::quotemsg(smb_t* smb, smbmsg_t* msg, bool tails)
 				wrap_cols = cfg.xedit[useron_xedit-1]->quotewrap_cols;
 			if(wrap_cols == 0)
 				wrap_cols = cols - 1;
-			wrapped=::wordwrap(buf, wrap_cols, org_cols - 1, /* handle_quotes: */TRUE);
+			wrapped=::wordwrap(buf, wrap_cols, org_cols - 1, /* handle_quotes: */TRUE, is_utf8);
 		}
 		if(wrapped!=NULL) {
 			fputs(wrapped,fp);
-- 
GitLab