Link to home
Start Free TrialLog in
Avatar of hrolsons
hrolsonsFlag for United States of America

asked on

VB6 URLEncode

I'm trying to encode a string to be passed as a URL.  The code I'm currently running is:

Public Function URLEncode( _
    ByVal URL As String, _
    Optional ByVal SpacePlus As Boolean = True) As String
    
    Dim cchEscaped As Long
    Dim HRESULT As Long
    
    If Len(URL) > INTERNET_MAX_URL_LENGTH Then
        Err.Raise &H8004D700, "URLUtility.URLEncode", _
                  "URL parameter too long"
    End If
    
    cchEscaped = Len(URL) * 1.5
    URLEncode = String$(cchEscaped, 0)
    HRESULT = UrlEscape(URL, URLEncode, cchEscaped, URL_ESCAPE_PERCENT)
    If HRESULT = E_POINTER Then
        URLEncode = String$(cchEscaped, 0)
        HRESULT = UrlEscape(URL, URLEncode, cchEscaped, URL_ESCAPE_PERCENT)
    End If

    If HRESULT <> S_OK Then
        Err.Raise Err.LastDllError, "URLUtility.URLEncode", "System error"
    End If
    
    URLEncode = Left$(URLEncode, cchEscaped)
    If SpacePlus Then
        URLEncode = Replace$(URLEncode, "+", "%2B")
        URLEncode = Replace$(URLEncode, " ", "+")
    End If
End Function

Open in new window


Some bad stuff is getting through into the URL and I can't figure out why.
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

Wow, it's been almost 20 years since I worked with VB 6, but can you elaborate on what "bad stuff" is?
Avatar of hrolsons

ASKER

I'm ultimately sending the data from VB6 to PHP to MySQL and when I have:
'Empire.).
<strong>Issuan

Open in new window

in VB6, it's not saving to the db in MySQL.  Let me try to give a stronger example than above, as soon as I can wrap my head around it.
If PHP is the database client, it should be the one doing any filtering. Regardless of what you do in VB 6, PHP should be using prepared statements to insert, to avoid injection vulnerabilities.
Yes, when the field starts with a single quote, it's giving me issues inserting into the db.
Yep, because you're probably not using prepared statements in PHP, so the single quote is disrupting the query structure.

Don't worry about filtering out values in VB - just do the filtering in PHP and use a prepared statement to insert the result.
print urlencode("'Empire.).<strong>Issuan")
'Empire.).%3Cstrong%3EIssuan

Open in new window


I was originally trying to process the data in PHP, but got confused on the INSERT.  I tried addslashes(), stripslashes(), htmlspecialchars(), to no avail.
I couldn't figure out the syntax for mysqli_real_escape_string()

What does your PHP code look like (remember to remove any credentials or sensitive info before sharing) ?
Pretty basic I think:

<?php
   foreach ($_GET as $key => $value) {
      $$key = $value;
   }

   $servername = "mysql.xxxxx.com";
   $username = "xxxxx";
   $password = "xxxxx";
   $dbname = "xxxxx";
   
   // Create connection
   $conn = new mysqli($servername, $username, $password, $dbname);
   // Check connection
   if ($conn->connect_error) {
     die("Connection failed: " . $conn->connect_error);
   }

   $theitem_description=mysqli_real_escape_string($theitem_description);
   $theebay_title='';
   
   $sql = "INSERT INTO xxxxx (bookmark, theitem_description) VALUES ('$thebookmark', '$theitem_description')";
   echo "<P>*****$sql*****<P>";

   if ($conn->query($sql) === TRUE) {
     echo "New record created successfully";
   } else {
     echo "Error: " . $sql . "<br>" . $conn->error;
   }

   $conn->close();

?>

Open in new window

Try this (changed part in bold):

<?php
   foreach ($_GET as $key => $value) {
      $$key = $value;
   }

   $servername = "mysql.xxxxx.com";
   $username = "xxxxx";
   $password = "xxxxx";
   $dbname = "xxxxx";
   
   // Create connection
   $conn = new mysqli($servername, $username, $password, $dbname);
   // Check connection
   if ($conn->connect_error) {
     die("Connection failed: " . $conn->connect_error);
   }




  $stmt = $conn->prepare("INSERT INTO xxxxx (bookmark, theitem_description) VALUES (?, ?)");


   $stmt->bind_param("ss", $thebookmark, $theitem_description);


   if ($stmt->execute() === TRUE) {
     echo "New record created successfully";
   } else {
     echo "Error: " . $sql . "<br>" . $conn->error;
   }




   $conn->close();




?>

Open in new window

I changed your code from xxxxx to my table name and the PHP code wouldn't run.

You're doing some things I'm not familiar with.
ASKER CERTIFIED SOLUTION
Avatar of gr8gonzo
gr8gonzo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you for the amazing answer.
It's failing on:
$stmt->bind_param("ss", $thebookmark, $theitem_description);

Open in new window

When I comment out "//" that line I get no error.  I don't see anything wrong.
I can't help but wonder if my PHP isn't configured right.
It's pretty unusual to have an error on that line unless the prepare() step has failed, which would usually indicate an error in the query structure itself.

Do you have errors logged or displayed? If so, that should tell you what specifically failed and why.

However, given the probability of what's failing, you can explicitly check for errors in case there's something wrong with the preparation or binding steps:

$stmt = $conn->prepare(...);
if($stmt === false)
{
  die("Error when preparing the query: " . $conn->error);
}

$bind_param_result = $stmt->bind_param("ss", $thebookmark, $theitem_description);
if($bind_param_result === false)
{
  die("Error while binding the parameters: " . $stmt->error);
}

...rest of code...

Open in new window


If you're able to use regular mysqli functions, then it shouldn't be a PHP configuration problem.
Error when preparing the query: Unknown column 'theitem_description' in 'field list'

Open in new window

I forgot that I renamed a field in order to post it on here.
So So SO Close!!!  It's giving me a hard time when the _GET value equals:

#ark:\/81055\/

Open in new window

It's throwing:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>


Open in new window

Here is the VB code I'm calling:
theitem_description = "#ark:\/81055\/"
x = "http://" & "www.xxxxx.com/test.php?thebookmark=" & thebookmark & "&theitem_description=" & theitem_description
Set http = New WinHttpRequest
http.Open "GET", x, "False"
Debug.Print x
http.Send
myval = http.ResponseText

Open in new window

And to run this , test.php equals:
<?php
   echo "This is a test";
?>

Open in new window

You still need to URL-encode the parameter values when sending them (you just don't need to actually -filter- out any values with the VB6 code).
Which brings us back to the original question as to why my URLEncode() isn't working right?
What I'm trying to say is that your URL encode function is probably fine - chances are it was just the PHP failing all along because you weren't handling the input safely.

However, I'll add that I'm not familiar with UrlEscape() so I'm only guessing here that it is a UTF-8-compatible method for URL-encoding a string.

I don't know if this helps anything, but:

Right now it's failing to URLEncode and failing on:
0x000

Open in new window


Make sure you've enabled PHP error logging (it's a setting in your php.ini file - if you change it, you have to restart the PHP or web service) so you can see what the actual error is.

There's no need to URLEncode "0x00" since that's technically a valid string. I understand that's shorthand hex for a null byte, but if the original source is just a string, then URLEncode would just see it as a string - it would not automatically infer that it was intended to be a hex value. So the PHP error log might illuminate the root cause.
I'm on a shared server so not sure if I have access to php.ini.
You probably have some access to it or else have a means of enabling or viewing the be PHP error log