Okay, so I've produced a piece of code looking like this. It's the peak, the epitome of simplicity, no doubt about it.
// [1] have accesslevel 0 (admin privs), or
// [2] are the author of the item (identified by session and database id)
if(isset($_GET['delete_id']){
$delete_id = // Sanitation removed for simplicity
$author_id = // DB operations removed for simplicity
if($_SESSION['accesslevel'] == 0 || $author_id == $_SESSION['user_id']){
if(mysql_query("DELETE FROM table WHERE id=$delete_id") or $output = 'Error removing item '. $delete_id)
$output = 'Item ' . $delete_id . 'deleted!';
} else {
$output = 'You do not have the privileges required to remove this item!'
}
}
Then we have a couple of unrelated clauses, and the output of the list of items, which of course displays a possibility to delete the item if the privileges are upheld. It looks like follows:
while($row = mysql_fetch_array($result)){
$button_delete = ''; // Empty if unprivileged
if( /* $_SESSION['user_id'] is privileged enough */){
$button_delete = "<a href='?page=$_GET[page]&delete_id=$row[id]'><input type='button' value='Delete'></a>";
}
echo "<tr><td>$row[item_name]</td> [...] <td>$button_delete</td></tr>";
// And finally the code to output the deletion-status, down here
echo $output;
Assuming all the code I decided to leave out are all without any errors and definitely doesn't interfere with the code above, can you find any errors?
My original source-file contained roughly 150 lines of code, and I was baffled when I found a very, very strange bug.
- If I'm not privileged enough, I get the correct message that I lack privileges and the query is, of course, not executed.
- If I'm privileged, the query is indeed executed, meaning we've entered the first IF-clause. ALAS, I get the same message as above (!!)
We simultaneously exeute the content of both the IF and the ELSE clauses. Whoa.
Isolating only the logical comparison part and running it, I was unable to reproduce the error. So some other part of the code had to be interfering. But there were no conflicts, there *could not be* any conflicts. Commenting my way through the code, I was assured of that. After spamming my code with outputs in the different clausules, (which only led me closer to the brink of insanity, since even though the code seemed to evaluate true (the query was executed), I did not get any output), the error was at long last stumbled upon.
<a href='?page=$_GET[page]&delete_id=$row[id]'><input type='button' value='Delete'></a> This here, ladies and gentlemen, was the perpetrator. The caused me such grief. Even though it was not supposed to have any effect on the code's workings (it was not in a form, it's value was never registered), it somehow managed to set some property amiss. Now, I'm not very well versed in the Document Object Model, but that my querystring was somehow "invisibly altered", and on top of that, that my evaluations were compared and their respective clauses were exectued before some variables were set (or set over again, as it appeared...), sounds very unreasonable, or at the very least, odd.
Just a short note regarding the debugging. For validating a user as author, I performed a simple query selecting the author's ID, storing it in a variable. When outputting this variable, before any DELETE-queries or basically anything at all was exectued, with unfulfilled privileges, I got the output correctly. But, when outputting it when it was true, it somehow was empty. Like the post had been deleted before the query was executed.
I'll write that again.
- Get author ID
- Echo this ID for debugging
- Compare to current user
- If true, perform DELETE
- If false, set errormessage
If #3 was false, we got the errormessage, and the author ID was echoed.
If #3 was true, we STILL got the errormessage, but the author ID was empty. The post was deleted before we performed the evaluation allowing the program to delete it, but ONLY when we actually DID have the permissions to do so.
My head still hurts...
Got any explanations to this? I'd love to hear about it!