Davo
Davo

Reputation: 181

Javascript variable passing text string with apostrophe, get cut off?

I have a block of code that contains this line in a form:

<form>
<input type='hidden' name='title' value='"+val.sources[0].title+"'>
</form>

On the receiving end, I have a document that grabs the data like so:

$title = $_POST['title'];

This is being inserted into a database, but any "title" that contains an apostrophe is getting cut off at the apostrophe - see example:

"I Don't Want It" -----> results in "I Don"

"David'd Car" -----> results in "David"

etc.

I did try several php str_replace efforts on the processing side with no luck, such as:

$title = str_replace(''', '"', $_POST['title']);

It appears that the data is not being sent properly, but not sure, Any Suggestions

THIS IS THE FULL BLOCK AND INSERT BELOW THAT:

$.each(playlist, function(index, val) {
        playlistHtml  += "<li class='playlist-item "+((val.sources[0].title).substring(0, 1)).toUpperCase()+"'><span class='jp-list-title' style='border-bottom:1px dotted #d2d2d2'>"
        +
        "<table border='0' style='width:100%;margin:8px 0px'><tr>"
        +
        "<td style='width:45px;text-align:center'>";
        // -----
        // ---- ICONS that preceed track -- YouTube, Vimeo, Audio, Movie etc. -----
        // -----
        if (val.sources[0].media == "0"){ // youtube
            playlistHtml += "<span style='min-width:30px;text-align:center;color:#5fabec;font-size:20px'><i class='fab fa-youtube' aria-hidden='true'></i></span>"
        }
        if (val.sources[0].media == "1"){ // vimeo
            playlistHtml += "<span style='min-width:30px;text-align:center;color:#5fabec;font-size:20px'><i class='fab fa-vimeo-square' aria-hidden='true'></i></span>"
        }
        if (val.sources[0].media == "2"){ // soundcloud
            playlistHtml += "<span style='min-width:30px;text-align:center;color:#5fabec;font-size:20px'><i class='fab fa-soundcloud' aria-hidden='true'></i></span>"
        }
        if (val.sources[0].media == "3"){ // MP3 audio link
            playlistHtml += "<span style='min-width:30px;text-align:center;color:#5fabec;font-size:20px'><i class='fas fa-file-audio' aria-hidden='true'></i></span>"
        }
        if (val.sources[0].media == "4"){ // MP4 video link
            playlistHtml += "<span style='min-width:30px;text-align:center;color:#5fabec;font-size:20px'><i class='fas fa-film' aria-hidden='true'></i></span>"
        }
        if (val.sources[0].media == "5"){  // radio link
            playlistHtml += "<span style='min-width:30px;text-align:center;color:#5fabec;font-size:20px'><i class='fas fa-microphone' aria-hidden='true'></i></span>"
        }

        playlistHtml  += "</td><td style='font-size:<?php echo $fontsize; ?>';padding:13px'><div class='playlist_abbrev'><span onclick='executeParent()'>"+val.sources[0].title+"&nbsp;&nbsp;<span style='color:#d2d2d2'>|</span>&nbsp;&nbsp;<span style='font-size:<?php echo $fontsize_artist; ?>'>"+val.sources[0].artist+"</span></div></td>"
        + /* TITLE -- ADD TO FAV */
        "<td style='font-size:<?php echo $fontsize; ?>';padding:13px'><form id='add Favorite' action='process_fav_add.php' method='post'><input type='hidden' name='active' value='1'><input type='hidden' name='mediatype' value='"+val.sources[0].media+"'><input type='hidden' name='title' value='"+val.sources[0].title+"'><input type='hidden' name='artist' value='"+val.sources[0].artist+"'><input type='hidden' name='source_url' value='"+val.sources[0].src+"'><input type='hidden' name='playlists' value='My-Favorites'><input type='hidden' name='user' value='<?php echo $id; ?>'><input type='hidden' name='playlist' value='<?php echo $playlist; ?>'><button class='playlist-favorite' id='sub'><i class='far fa-heart'></i></button></form></td>"
        "</tr></table></span></li>"

INSERT

$active = $_POST['active'];
$mediatype = $_POST['mediatype'];
$title = $_POST['title'];
// $title = str_replace(''', '"', $_POST['title']);
$artist = $_POST['artist'];
$source_url = $_POST['source_url'];
$playlists = $_POST['playlists'];
$user = $_POST['user'];
$playlist = $_POST['playlist'];

$rec_insert = mysql_query("INSERT INTO member_tracks(active, mediatype, title, artist, source_url, playlists, user) VALUES ('$active', '$mediatype', '$title', '$artist', '$source_url', '$playlists', '$user')");
if(! $rec_insert )
{
    die('Could not enter data: ' . mysql_error());
} else {
    echo '<html>';
    echo '<head>';
    echo '<title>MusicPax</title>';
    echo '</head>';
    echo '<body style="background-color:#000;font-family:sans-serif;color:#666">';
    echo '<table width="100%" height="100%"><tr><td width="100%" height="100%">';
    echo '<p style="padding-bottom:20px;text-align:center;font-size:18px;letter-spacing:2px">TRACK ADDED SUCCESSFULLY</p>';
    echo '</td></tr></table>';
    echo '</body>';
    echo '</html>';
}

// $conn->close();

Upvotes: 1

Views: 1236

Answers (2)

trincot
trincot

Reputation: 350477

There are several issues.

  1. First the immediate problem of placing the title in the input element via some jQuery code. You currently build a string that is made up like this:

    "....<input value='" + val.sources[0].title + "'>...."
    

    As you already detected, a quote in the title value will break things. You can escape the title by using this function:

    function escapeHtmlAttribute(s) {
        return s.replace(/&/g, "&amp;").replace(/'/g, "&apos;");
    }
    

    This encodes the quotes with the appropriate HTML entity, and also escapes the ampersand as otherwise it could be misunderstood as the start of an HTML entity.

    So then your string would be built like this:

    "....<input value='" + escapeHtmlAttribute(val.sources[0].title) + "'>...."
    
  2. Secondly, you have a similar problem in your PHP code, where you inject the strings directly in your SQL. Not only does it pose a problem with a quote in the title, it opens the door to malicious SQL injection. In the old days you would be advised to circumvent that by calling mysql_real_escape_string:

    "INSERT INTO ....... VALUES(......, '" + mysql_real_escape_string($title) + "', ....)"
    

    ... but it is much better to not inject any strings at all and use prepared statements. This brings me to the following point:

  3. You are using the mysql_ set of functions, which were deprecated in PHP 5.0 and are no longer supported since PHP 7. You really must step away from them. Do it today. Instead, the MySQLi or PDO_MySQL extension should be used. Furthermore, you should use prepared statements. That way you no longer need any escaping and do not have any risk of SQL injection. Please read How can I prevent SQL injection in PHP?

Upvotes: 1

Mamun
Mamun

Reputation: 68913

You can try with Template Literals:

<input type='hidden' name='title' value="${val.sources[0].title}">

Upvotes: 1

Related Questions