views:

80

answers:

5

Hi Guys, another brain teaser.

This isn't the usual "but Apostrophes are breaking my Queries" as I know all about escaping and sanitising so I'll get right too it.

Many many things are stored in a db with names like "Assassin's" and "Babe's" which end up "Assassin\'s" and "Babe\'s", recovering is good but searching via text is... painful.

LIKE "%Babe\'s%" has no results, "%Babe\\'s" has no results, "%Babe\''s" has no results.

BUT if I go to the server directly then they will all produce results.

In other words, the SAME query totally unedited will work directly in the MySQL engine but sent via php's mysql api it produces no matched results.

Any ideas what could cause this? (I've checked 100 times the amount of slashes etc, is there a character set issue?"

Many many many many thanks in advance.

edit:

I think i better make myself more clear:

"SELECT title FROM games WHERE title LIKE "%assassin\\\'s%"; (Since SQL should escape the apostrophe and one of the slashes will turn into the slash that was stored, since we're looking for "Assassin\'s Creed" in this example)

edit2: Sow we've figured out this is caused by having escaped escapes in the actual db caused by poor sanitising. Currently I'm in the process of trying to cleanup the db and the input method.

edit3: It seems like magic quotes were on somehow... I swear that was turned off! However it wasn't just that. The DB wrapper which is in place for this site has a clean event and also a pre-clean which caused the issue. That has been fixed now and now I'm running a script to (hopefully) cleanse the db...

+1  A: 

Did you try to use mysql_real_escape_string, also check if magic_quotes is enabled and messing with your strings

rmontagud
Yes, mysql_real_escape_string is what I've used but I've also produced the statement raw just before it is sent to the server. As I know with magic_quotes, they are only when data enters PHP? I could be mistaken ofc but if that was the case the single escape would work since the only problem with the magic_quotes is the extra escapes.
Dorjan
+1  A: 

When you escape an apostrophe so that you can store it in MySQL, the back slash isn't stored.

So try this:

SELECT title FROM games WHERE title LIKE "%assassin\'s%";

Instead of:

SELECT title FROM games WHERE title LIKE "%assassin\\\'s%";
Marcus Adams
Unfortunately in this case the person prior to me used a manual escape where the escape IS stored in the db.
Dorjan
Even a manual escape won't have MySQL storing the back slash. Are you saying that when you `SELECT * FROM title`, you see things like `'Assassin\'s Creed'`? If you are, then it was improperly escaped, and your data is broken.
Marcus Adams
That is what I'm saying. It is all over there db; it must've been triple escaped.
Dorjan
A: 

SELECT title FROM games WHERE title REGEXP "assassin\'s";

Think of REGEXP as a more powerful, less picky "LIKE" in MySql....Not the be-all, end-all, but another cool tool in the shop.

bpeterson76
I never knew of this.. I will give it a shot tomorrow. Thanks.
Dorjan
+5  A: 

I would seriously consider fixing the data in your database.

Now, having said that, MySQL recognizes both \' and '' as an escaped apostrophe. That is, unless the server mode is set to use strict SQL, in which case only '' is recognized.

The data is most certainly getting double-escaped on entry, most likely once when the user enters it (by magic_quotes_gpc, which uses addslashes) and again by mysql_real_escape_string when you call it.

This would turn Assassin's Creed into Assassin\\\'s Creed, which would ultimately get stored as Assassin\'s Creed.

I highly recommend disabling magic_quotes_gpc if you can, as it causes more problems than it fixes.

R. Bemrose
I think fixing the db and the input function would be the best course of action. Cheers all, I'll leave this open until I fix it then give the answer to whom helped the best :)Thanks everyone again
Dorjan
I've fixed the db and it worked. Big job but well worth it since now everything is acting as it should. I've cleaned up the input too so we shouldn't have anymore broken data.Thanks again to everyone
Dorjan
A: 

As documentation says, slashes in LIKE and REGEXP clauses must be doubled

Edit: wrong link corrected

Col. Shrapnel
Yes, we know this but unfortunately since the date actually is storing the slash this is causing "LIKE" not to bring back a result when going through. hecne why this is an odd question as it isn't acting as you'd expect. As others have said the dataset itself seems to be broken to MySQL standards which is causing this to fail.
Dorjan
@Dorjan anyway you will still need this after you repair your data
Col. Shrapnel
also if you read the question you'd quickly realise that we've tried "just doubling the slashes"
Dorjan
"SELECT title FROM games WHERE title LIKE "%assassin\\\'s%";is the example give to search for "Assassin\'s Creed".
Dorjan
@Dorjan You've tried it among other blind shoots, but this shouldn't be a try but a rule. :)
Col. Shrapnel
@Dorjan thank you for your "thank you" :)
Col. Shrapnel
It wasn't a blind shoot... I escaped the apostrophe with both types, with extra for the extra false data.The solution I tried didn't work from the PHP end but did IN the SQL engine directly. Did you even read that part?
Dorjan