I have the following jQuery that POSTS data to a form to allow a user to change their password.

$(function() {
  $("#frmChangePW .submit").click(function() {
		var old_pw = $("#old_pw").val();
		var new_pw = $("#new_pw").val();
		var uid = $("#form_id").val();
		var dataString = 'form_id='+ uid + '&old_pw='+ old_pw + '&new_pw=' + new_pw;
		//var dataString = $("#frmChangePW").serialize();


	$.ajax({
		type: "POST",
  		url: "change-pw.php",
  		data: dataString,
  		success: function(response) {
      		if(response == 1){
    			$('#tools_pw2').append("<font size='1' color='red'><b>Success!</b></font>");
			}else{
    			$('#tools_pw2').append("an error occured");
			}
  		}
 	});
return false;
});
});

And here is the code for change-pw.php ... Basically get the user id, their existing pw, and their new pw, hash both. Compare the id and the hash of the current password to make sure they are allowed to update the record, then update the record.

	// Get variables and update the user's password
		$id = $_POST['form_id'];
		$cur = mysql_real_escape_string($_POST['old_pw']);
		$new = mysql_real_escape_string($_POST['new_pw']);

	$enc_cur = sha1($cur);
	$enc_new = sha1($new);

	$q = "UPDATE `users` SET `pw` = '".$enc_new."' WHERE `id` = '".$id."' AND `pw` = '".$enc_cur."'";
	$r = mysql_query($q) or die(mysql_error());
	$num = mysql_affected_rows();

The problem I am having is I allow users to have special characters such as $ or ! or # in their passwords, in fact I require it for complexity purposes. But it seems that some of the characters are completely ignored and in some cases, everything after it is ignored. Example, I created a user 'jdoe' with password = 123!#.

The result is that $cur becomes set to 123! and the # is completely ignored, and then $new never gets set because everything after # is just discarded.

I did some reading on stackOverflow that by using POST these issues of special characters should be solved. It didn't work so I tried using the .serialize() -- you'll see it's commented out above because that too didn't work.... I then tried urldecode() and htmlspecialchars_decode(). Both to no avail.

So what do I need to do to properly POST variables containing special characters to my pw update script so that the variables are set properly and life can go on?

TIA.

    Thread moved to ClientSide Technologies (since this has nothing to do with PHP).

    rsmith;11001903 wrote:

    The problem I am having is I allow users to have special characters such as $ or ! or # in their passwords, in fact I require it for complexity purposes. But it seems that some of the characters are completely ignored and in some cases, everything after it is ignored.

    It should make sense that non-alphanumeric characters tend to cause problems, since you aren't properly encoding those characters (such as when using the 'application/x-www-form-urlencoded' type of encoding).

    rsmith;11001903 wrote:

    I did some reading on stackOverflow that by using POST these issues of special characters should be solved.

    I don't think you read something correctly; the data needs to be encoded properly whether you're placing it in the query string or in a POST string (especially since the two really aren't any different as far as encoding goes).

    rsmith;11001903 wrote:

    It didn't work so I tried using the .serialize() -- you'll see it's commented out above because that too didn't work

    Well that is the proper way to go about what you're trying to do, so I would hesitate to accept the "didn't work" without some proof. For example, did you try printing out the resulting string (e.g. to the Javascript console or somewhere in the HTML document)? If so, what did it look like?

    Also, can you show us the relevant bits of HTML for the form that this code is to be interacting with?

    rsmith;11001903 wrote:

    .... I then tried urldecode() and htmlspecialchars_decode(). Both to no avail.

    Well it should make sense that neither of those worked, since a) neither of those are core Javascript functions (and I don't see any mention of how you defined those functions), and b) they would do the opposite of what you need to be doing (which is encoding the data, not decoding it).

    rsmith;11001903 wrote:

    So what do I need to do to properly POST variables containing special characters to my pw update script so that the variables are set properly and life can go on?

    .serialize() it. 🙂

      bradgrafelman;11001909 wrote:

      It should make sense that non-alphanumeric characters tend to cause problems, since you aren't properly encoding those characters (such as when using the 'application/x-www-form-urlencoded' type of encoding).

      Where do I specify that? in the <form> field or the jQuery?

      bradgrafelman;11001909 wrote:

      Well that is the proper way to go about what you're trying to do, so I would hesitate to accept the "didn't work" without some proof. For example, did you try printing out the resulting string (e.g. to the Javascript console or somewhere in the HTML document)? If so, what did it look like?

      Yes, when I attempt to debug it I add a line to the jQuery that when submit is clicked so I can see what is being sent to the php script

      alert(dataString);
      
      bradgrafelman;11001909 wrote:

      Also, can you show us the relevant bits of HTML for the form that this code is to be interacting with?

      Sure...

              echo "<form name='frmChangePW' id='frmChangePW' method='post' action=''>";
      		echo "<span class='mya1'>Current Password</span><br />";
      		echo "<input type='password' name='old_pw' id='old_pw' class='textbox' /><br />";
      		echo "<span class='mya1'>New Password</span><br />";
      		echo "<input type='password' name='new_pw' id='new_pw' class='textbox' /><br />";
      		echo "<span class='mya1'>Confirm New Password</span><br />";
      		echo "<input type='password' name='new_pw_conf' id='new_pw_conf' class='textbox' /><br />";
      		echo "<input type='hidden' name='form_id' id='form_id' value='".$id."' />";
      		echo "<input type='submit' id='changepw' class='submit' value='change' /> <input type='reset' class='submit' value='reset' />";
      

      Thanks again.

        So what did dataString look like when you used the .serialize() method?

          old_pw=123!&#37;23&new_pw=45678!!&new_pw_conf=45678!!&form_id=23
          

          The %23 is the # in the test user password.

            rsmith;11001917 wrote:
            old_pw=123!%23&new_pw=45678!!&new_pw_conf=45678!!&form_id=23
            

            Looks fine to me. Why do you say this doesn't work?

            rsmith;11001917 wrote:

            The %23 is the # in the test user password.

            Yes, that would make sense, since 0x23 is the numerical value of the ASCII character '#'.

              Okay I put the serialize statement back in for dataString... The actual password change appears to work now but the success() function isn't returning properly. The row is obviously getting updated on change-pw.php so the affected rows = 1 but the .append() is still saying an error occurred instead of "Success"

                Have you tried the same debugging test as before, e.g. directly outputting the value of the 'response' parameter before you use it in order to see exactly what it contains?

                EDIT: Also, what does your PHP code do after the SQL stuff you showed us? In your PHP snippet above, your code doesn't actually echo/print anything.

                  The only thing the php script does after the query commands above is

                  echo $num;
                  

                  Which outputs 1 if the row is updated successfully.

                  I commented out the error message and instead put this:

                  $('#tools_pw2').append(response);
                  

                  Changed the password and it added "1" to the DIV indicating a successful change so since the response == 1 it should've output "Success!"

                    I got it! Had to make it as follows for some reason

                    if(response == "1")
                    

                    Now it's working. Thanks brad for all the help.

                      rsmith;11001927 wrote:

                      Changed the password and it added "1" to the DIV indicating a successful change so since the response == 1 it should've output "Success!"

                      But who ever said that 'response' is equal to the number 1? The string "1" and the number 1 are quite different. Likewise, the string "1" is different than the string " 1 " or " 1" or... etc.

                      Try doing something like:

                      alert('response value: "' + response + '"\nInteger response value: " + parseInt(response) )

                      What does the output of that look like?

                      (Note the using alert()'s for debugging is a little... well, just know that you can replace 'alert' with 'console.log' in the above code snippet if you'd rather use the Javascript console for debugging instead.)

                      EDIT: Oops.. busy composing this reply while you figured out the issue I was busy addressing. 😉 Hopefully the first part of my post above will explain why, though.

                        Write a Reply...