From a92bb182d91ae98b2a2bc7787d5650050868f1f1 Mon Sep 17 00:00:00 2001
From: Macil Tech <maciltech@gmail.com>
Date: Tue, 2 Apr 2013 17:28:04 +0800
Subject: [PATCH] Fix display issues with RTL control characters in post names,
 subjects, and filenames.

---
 inc/display.php                               | 33 +++++++++++++++++++
 .../Twig/Extensions/Extension/Tinyboard.php   |  1 +
 templates/post_reply.html                     |  8 ++---
 templates/post_thread.html                    | 14 ++++----
 4 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/inc/display.php b/inc/display.php
index 57110224..ab96eb26 100644
--- a/inc/display.php
+++ b/inc/display.php
@@ -213,6 +213,39 @@ function truncate($body, $url, $max_lines = false, $max_chars = false) {
 	return $body;
 }
 
+function bidi_cleanup($str){
+	# Closes all embedded RTL and LTR unicode formatting blocks in a string so that
+	# it can be used inside another without controlling its direction.
+	# More info: http://www.iamcal.com/understanding-bidirectional-text/
+	#
+	# LRE - U+202A - 0xE2 0x80 0xAA
+	# RLE - U+202B - 0xE2 0x80 0xAB
+	# LRO - U+202D - 0xE2 0x80 0xAD
+	# RLO - U+202E - 0xE2 0x80 0xAE
+	#
+	# PDF - U+202C - 0xE2 0x80 0xAC
+	#
+	$explicits	= '\xE2\x80\xAA|\xE2\x80\xAB|\xE2\x80\xAD|\xE2\x80\xAE';
+	$pdf		= '\xE2\x80\xAC';
+
+	$stack = 0;
+	$str = preg_replace_callback("!(?<explicits>$explicits)|(?<pdf>$pdf)!", function($match) use (&$stack) {
+		if (isset($match['explicits']) && $match['explicits']) {
+			$stack++;
+		} else {
+			if ($stack)
+				$stack--;
+			else
+				return '';
+		}
+		return $match[0];
+	}, $str);
+	for ($i=0; $i<$stack; $i++){
+		$str .= "\xE2\x80\xAC";
+	}
+	return $str;
+}
+
 function secure_link_confirm($text, $title, $confirm_message, $href) {
 	global $config;
 
diff --git a/inc/lib/Twig/Extensions/Extension/Tinyboard.php b/inc/lib/Twig/Extensions/Extension/Tinyboard.php
index 0a128e7b..7592d1b4 100644
--- a/inc/lib/Twig/Extensions/Extension/Tinyboard.php
+++ b/inc/lib/Twig/Extensions/Extension/Tinyboard.php
@@ -25,6 +25,7 @@ class Twig_Extensions_Extension_Tinyboard extends Twig_Extension
 			'until' => new Twig_Filter_Function('until'),
 			'split' => new Twig_Filter_Function('twig_split_filter'),
 			'push' => new Twig_Filter_Function('twig_push_filter'),
+			'bidi_cleanup' => new Twig_Filter_Function('bidi_cleanup'),
 			'addslashes' => new Twig_Filter_Function('addslashes')
 		);
 	}
diff --git a/templates/post_reply.html b/templates/post_reply.html
index ddd0afd4..c5735a0e 100644
--- a/templates/post_reply.html
+++ b/templates/post_reply.html
@@ -7,14 +7,14 @@
 	<label for="delete_{{ post.id }}">
 		{% if post.subject|length > 0 %}
 			{# show subject #}
-			<span class="subject">{{ post.subject }}</span> 
+			<span class="subject">{{ post.subject|bidi_cleanup }}</span> 
 		{% endif %}
 		{% if post.email|length > 0 %}
 			{# start email #}
 			<a class="email" href="mailto:{{ post.email }}">
 		{% endif %}
 		{% set capcode = post.capcode|capcode %}
-		<span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name }}</span>
+		<span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name|bidi_cleanup }}</span>
 		{% if post.trip|length > 0 %}
 			<span {% if capcode.trip %}style="{{ capcode.trip }}" {% endif %}class="trip">{{ post.trip }}</span>
 		{% endif %}
@@ -66,9 +66,9 @@
 			{% if config.show_filename and post.filename %}
 				, 
 				{% if post.filename|length > config.max_filename_display %}
-					<span title="{{ post.filename }}">{{ post.filename|truncate(config.max_filename_display) }}</span>
+					<span class="postfilename" title="{{ post.filename|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
 				{% else %}
-					{{ post.filename }}
+					<span class="postfilename">{{ post.filename|bidi_cleanup }}</span>
 				{% endif %}
 			{% endif %}
 		)
diff --git a/templates/post_thread.html b/templates/post_thread.html
index cf93bed0..d7a62d4f 100644
--- a/templates/post_thread.html
+++ b/templates/post_thread.html
@@ -22,11 +22,11 @@
 		{% endif %}
 		{% if config.show_filename and post.filename %}
 			, 
-			{% if post.filename|length > config.max_filename_display %}
-				<span title="{{ post.filename }}">{{ post.filename|truncate(config.max_filename_display) }}</span>
-			{% else %}
-				{{ post.filename }}
-			{% endif %}
+			{% if post.filename|length > config.max_filename_display %}

+				<span class="postfilename" title="{{ post.filename|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>

+			{% else %}

+				<span class="postfilename">{{ post.filename|bidi_cleanup }}</span>

+			{% endif %}

 		{% endif %}
 	)
 	</span></p>
@@ -50,14 +50,14 @@
 	<label for="delete_{{ post.id }}">
 		{% if post.subject|length > 0 %}
 			{# show subject #}
-			<span class="subject">{{ post.subject }}</span> 
+			<span class="subject">{{ post.subject|bidi_cleanup }}</span> 
 		{% endif %}
 		{% if post.email|length > 0 %}
 			{# start email #}
 			<a class="email" href="mailto:{{ post.email }}">
 		{% endif %}
 		{% set capcode = post.capcode|capcode %}
-		<span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name }}</span>
+		<span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name|bidi_cleanup }}</span>
 		{% if post.trip|length > 0 %}
 			<span {% if capcode.trip %}style="{{ capcode.trip }}" {% endif %}class="trip">{{ post.trip }}</span>
 		{% endif %}