1

First off, this is not a duplicate, as I have checked a number of other listings of this title and have got no working resolution as of yet.

This is my file, it is the functional part of a URL Shortener, completely hand-made from scratch by myself, so its gonna look messy.

<?php

class URLShortener
{
    protected $messages = Array();
    protected $db;
    protected $shorturl;
    protected $lurl;

    public function __construct()
    {
        try 
        {
            $this -> dbConnect();
            if ($this -> validateInput())
            {
                $stmt = $this -> db -> prepare("INSERT INTO `redir` (`shorturl`, `longurl`, `disabled`, `aip`) VALUES (?,?,0,?);");
                $stmt -> bind_param('sss', $this -> shorturl, $_POST['longurl'], $_SERVER['REMOTE_ADDR']);
                $stmt -> execute();
                $this -> addMessage("Assigned a short url of ". $this -> shorturl .".",1);
            }
        }
        catch (Exception $e)
        {
            $this -> addMessage($e -> getMessage(), 4);
        }
    }

    protected function validateInput()
    {
        if (empty($_POST['longurl']))
        {
            $this -> addMessage('Please enter a URL.', 2);
            $this -> lurl = true;
        }
        elseif (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i",$_POST['longurl']))
        {
            $this -> addMessage('Please enter a valid URL.');
            $this -> lurl = true;
        }
        else
        {
            $stmt = $this -> db -> prepare("SELECT `shorturl` FROM `redir` WHERE `longurl` =  ?;");
            $stmt -> bind_param('s', $_POST['longurl']);
            $stmt -> execute();
            //$stmt -> store_result();
            if ($stmt->num_rows > 0)
            {
                try
                {
                    $result = $stmt -> get_result(); // WHY DONT YOU EXIST?
                }
                catch (Exception $e)
                {
                    $this -> addMessage($e -> getMessage(), 4);
                }
                if($result){
                    while ($row = $result->fetch_array(MYSQLI_NUM))
                    {
                        $this -> addMessage('This URL is already shortened to <a href="http://ndlee.com/'.$row[0].'">'.$row[0].'</a>',3);
                        $this -> lurl = true;
                    }
                }
            }
        }

        if (empty($_POST['shorturl']))
        {
            $this -> shorturl = substr(str_shuffle(MD5(microtime())), 0, 10);
        }
        else
        {
            if (!preg_match("^[a-zA-Z0-9]*$^",$_POST['shorturl']) AND strlen($_POST['shorturl']) > 20)
            {
                $this -> addMessage('Your custom URL contained illegal characters, or was too long. A random URL has been assigned instead.',2);
                $this -> shorturl = substr(str_shuffle(MD5(microtime())), 0, 10);
            }
            else
            {
                $this -> shorturl = $_POST['shorturl'];
            }
        }
        $stmt1 = $this -> db -> prepare("SELECT `shorturl` FROM `redir` WHERE `shorturl` =  ?;");
        if( ! $stmt1 = $this -> db -> prepare("SELECT `shorturl` FROM `redir` WHERE `shorturl` =  ?;"))
        {
            $this -> addMessage('Error: ' . $db->error,4);
        }
        else
        {
            $stmt1 -> bind_param('s', $this -> shorturl); // For some reason, this function doesn't exist. Yet it exists at line 44 and 18
            $stmt1 -> execute();
            //$stmt -> store_result();
            if ($stmt1->num_rows > 0)
            {
                $this -> addMessage('FATAL ERROR: We tried to assign you a random URL that was already assigned. This should never occur.',4);
                $this -> lurl = true;
            }
        }
        return empty($this -> lurl);
    }

    protected function dbConnect()
    {
        $this -> db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
        if (mysqli_connect_errno())
        {
            throw new Exception("Database connection failed: ". mysqli_connect_error());
        }
        return true;
    }

    protected function addMessage($m, $l)
    {
        if(empty($l))
        {
            $l = 1;
        }
        $this -> messages[] = "<div align=\"center\" class=\"notice{$l}\"><div style=\"float:left;\"><img src=\"../images/{$l}.png\"></div> {$m}</div><br>";
        return true;
    }

    public function getMessages()
    {
        return $this -> messages;
    }

    public function __destruct()
    {
        $this -> db -> close();
    }
}

class URLRetriever
{
    protected $messages = Array();
    protected $db;
    protected $lurl;

    public function __construct()
    {
        try
        {
            $this -> dbConnect();
            if ($this -> validateInput())
            {
                $sql = "SELECT * FROM redir WHERE shorturl = {$_GET['u']};";
                $result=mysqli_query($this -> db, $sql);
                //$count=mysqli_num_rows($result);
                if($result)
                {
                    $fuckimtired = mysqli_fetch_all($result); // Yeah, just ignore this, I'm just suffering lack-of-energy-drink-itus.
                    foreach ($fuckimtired as $row)
                    {
                        print_r($row);
                        $header('location: '.$row['longurl']);
                        break;
                    }
                }
                else
                {
                    $this -> addMessage("No such short URL. <a href=\"http://ndlee.com/\">Click here to return to NDLee.com</a>",4);
                }
            }
        }
        catch (Exception $e)
        {
            $this -> addMessage($e -> getMessage(), 4);
        }
    }

    protected function validateInput()
    {
        if(empty($_GET['u']))
        {
            $this -> lurl = true;
            $this -> addMessage("FATAL EXCEPTION: NO URL",4);
        }
        return empty($this -> lurl);
    }

    protected function dbConnect()
    {
        //$this -> db = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
        //$this -> db = new PDO('mysql:host='.DB_HOST .';dbname='.DB_NAME,DB_USER,DB_PASS);
        $this -> db = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
        return true;
    }

    protected function addMessage($m, $l)
    {
        if(empty($l))
        {
            $l = 1;
        }
        $this -> messages[] = "<div align=\"center\" class=\"notice{$l}\"><div style=\"float:left;\"><img src=\"../images/{$l}.png\"></div> {$m}</div><br>";
        return true;
    }

    public function getMessages()
    {
        return $this -> messages;
    }

    public function __destruct()
    {
        //$this -> db -> close();
    }
}
?>

Bind param believes that its prepare statement isn't an object. Mind you, my bind params are all based off one another and if 2 work, the third must as well. Infact, Line 44's statement and Line 90's statement are identical, except instead of selecting by longurl, we are selecting by shorturl.

Line 18

$stmt -> bind_param('sss', $this -> shorturl, $_POST['longurl'], $_SERVER['REMOTE_ADDR']);

Line 44

$stmt -> bind_param('s', $_POST['longurl']);

Those two instances work. But when we get to line 90,

$stmt1 -> bind_param('s', $this -> shorturl); // For some reason, this function doesn't exist. Yet it exists at line 44 and 18

I was following an answer at (Fatal error: Call to a member function bind_param() on a non-object) to validate my prepare statement, and now instead of proceeding normally, it spits out a non-fatal handled error, and returns me to the index as if everything worked fine.

I've checked the sql database and the url is being saved regardless of this error, however I believe it is not being checked for duplicate entries of short urls.

As you can see here, the script is saving urls fine. It just can't perform that added safety check

Is there anything you guys can see that I can't?

Community
  • 1
  • 1
MrDeeJayy
  • 47
  • 8

0 Answers0