2

I've got a problem with my little text to smiley/emoji function in php, which is based on str_replace. This is my code.

$smileys = array( ":inlove:" => "/smileys/smiley2.png",
                      ":cool:" => "/smileys/smiley3.png",
                      ":tongue:" => "/smileys/smiley4.png",
                      ":wow:" => "/smileys/smiley5.png",
                      ":smile:" => "/smileys/smiley15.png",
                      ":happy:" => "/smileys/smiley6.png",
                      ":funny:" => "/smileys/smiley7.png",
                      ":wink:" => "/smileys/smiley8.png",
                      ":worried:" => "/smileys/smiley10.png",
                      ":pokerface:" => "/smileys/smiley9.png",
                      ":poop:" => "/smileys/smiley12.png",
                      ":thinking:" => "/smileys/35_thinking.png",
                      ":triumph:" => "/smileys/49_triumph.png",
                      ":vulcan:" => "/smileys/109_vulcan.png",
                      ":pointup:" => "/smileys/102_point_up_2.png",
                      ":santa:" => "/smileys/135_santa.png",
                      ":spy:" => "/smileys/134_spy.png");

if(isset($_POST['message'])) {
    $messagePlain = $_POST['message'];
    $messageSmileys = $messagePlain;

    foreach($smileys as $key => $img) {
        $messageSmileys = str_replace($key, '<img src="' . $img . '" />', $messageSmileys);
    }

    $connection->query(// Message to db);
}

It works fine. But the problem is, when the user inputs more than ~14 emojis in a row, the HTML gets destroyed and it looks like this:

And the HTML source like this:

<div class="media-body">
                            <h4 class="media-heading">test <small>07. August. 2017 01:34</small></h4>
                             <img src="/smileys/smiley2.png" /> <img src="/smileys/smiley3.png" /> <img src="/smileys/smiley5.png" /> <img src="/smileys/smiley4.png" /> <img src="/smileys/smiley15.png" /> <img src="/smileys/smiley6.png" /> <img src="/smileys/smiley7.png" /> <img src="/smileys/smiley8.png" /> <img src="/smileys/smiley10.png" /> <img src="/smileys/smiley9.png" /> <img src="/smileys/smiley12.png" /> <img src="/smileys/49_triumph.png" /> <img src="/smileys/109_vulcan.png" /> <img src="/smileys/102_point_up_2.p                            </div>
</div>

Could someone help me with this? Why is the HTML tag for <img> suddenly destroyed?

Steve Piercy
  • 13,693
  • 1
  • 44
  • 57
Aarivex
  • 45
  • 1
  • 8
  • Oh wow. Looks like it's somewhere problematic with the way it is stored. Are you using any database? What's the storage size of the message in the DB? Looks like the truncation happens there. – Praveen Kumar Purushothaman Aug 06 '17 at 23:39
  • Just realised the row where it's stored in the database (message) has the size of 500. I increased it and will test it now. #edit: Works fine now. Thank you! – Aarivex Aug 06 '17 at 23:42
  • Rather than `foreach($smileys` you can just do `str_replace(array_keys($smileys), array_values($smileys), $string);` – chris85 Aug 07 '17 at 00:41

2 Answers2

1

Your database field probably has a length limit. You might want to raise that, but there’s a more important initial fix: store the original text in the database and perform the replacements on the output instead.

This is especially important because it looks like you’re probably vulnerable to HTML injection right now. Make sure to run htmlspecialchars before doing the replacement and be aware of how you need to encode your output to make it safe. How to prevent XSS with HTML/PHP? might be a good start.

Ry-
  • 218,210
  • 55
  • 464
  • 476
1

Looking at your output:

<img src="/smileys/smiley2.png" /> <img src="/smileys/smiley3.png" /> <img src="/smileys/smiley5.png" /> <img src="/smileys/smiley4.png" /> <img src="/smileys/smiley15.png" /> <img src="/smileys/smiley6.png" /> <img src="/smileys/smiley7.png" /> <img src="/smileys/smiley8.png" /> <img src="/smileys/smiley10.png" /> <img src="/smileys/smiley9.png" /> <img src="/smileys/smiley12.png" /> <img src="/smileys/49_triumph.png" /> <img src="/smileys/109_vulcan.png" /> <img src="/smileys/102_point_up_2.p

The above string's length is 499 characters. I strongly believe that your message field in the database table is limited to 500 characters or something and the output is truncated to those bits.

Solution / Suggestion

If you are using MySQL Database Server, I would strongly recommend you changing the database type from VARCHAR(500) to TEXT or LONGTEXT.

Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252