Codeigniter database query bug - does not return expected results - sql

I tested this query in my database, and it works fine:
select * from variables where value = 'commas-:-)';
I get a result. Now, I stored the value in a variable and use the query class.
$value = 'commas-:-)' <<< this is passed as a parameter
$query = "select * from variables where value = '$value'";
$this->db->query($query);
Now, this query works for every other value except for this one - but what's odd is that if I PRINT out the exact query (print_r of $query) and execute it on the database, it returns the correct result. So I'm left to think that the query class is screwing with my query, which it shouldn't because everything is properly escaped and $value is a string literal.
What is going on?

$sql = "SELECT * FROM variables WHERE value = ?";
$this->db->query($sql, array('commas-:-)'));
More info

$get_data = $this->db->from('variables')
->where('value', $value)
->get();
Hope this will work...!
try to use these things for checking the queries
echo $this->db->last_query();
print_r($this->db->result_array($get_data));

I found the issue - it was the rerouting function that was causing the mishap. More specifically, the segment filtering function within the route folder in the system core.
This is what happened:
I created an anchor with the encoded value (commas:-)) and I configured the route to reroute the uri to a function I had in my controller. Each time I clicked the link, the value gets passed, and (supposedly) rerouted to the function. Which it did, for almost all the values I used. Except this one.
1st assumption: the db query function is escaping the values. But I turned off the escape, as well as checked the query by printing. The value was correct. I then tried other query formats, and still no results. Conclusion: There's nothing wrong with the database query functions.
2nd assumption: the data must be corrupt - although the value is correct (I'm getting commas:-)), it's not returning anything except when I type in the value manually. So I tested this:
I created a seperate value, and set it equals to the one I typed in(the one that works). I then printed the original value(one passed) and the newly created value using VAR_DUMP.
Turns out, the argument value (one that doesn't work) is a string with length 14 whereas my new variable was a string with a length of 10. WTF? Conclusion: Something occured during the rerouting / passing process that changed the variable.
I went back to the config folder, and replace the variable $i in the reroute to the literal string value commas:-). And guess what? It worked perfectly. And just to make sure it wasn't the regex, I wrote my own custom regex and it matched fine, but the value was still being changed. So I decided to get under the hood.
I traced the URI manipulation in the routes class to the _explode_segment() function, which was used to perform the regex and analyse the uri for other variables. It also did this thing ...
_filter_uri($str)
for each part of the uri segment that was matched.
What did it do? It replaces programmable characters like ( and ) with their HTML ENTITY. Now, if you don't know, html entities have long lengths than url encoding. LOL. So what happened was this:
Original segment : commas-%3A-%29 <- very nice!
Filtered segment : commas-%3A-) <- NOOOOOOOOO! (the right paren encoded with &#41.)
urldecode("&#41") = string(4)
urldecode("%29") = string(1)
Fail.
or WIN?!

Related

Firestore rules variable in path compare to data

I want to compare a variable in the path with a entry in my document. I build the following rule:
match /{userId}/test/{cycle}/results {
//allow read: if 3 == get(/databases/$(database)/documents/$(userId)/status).data.number
allow read: if cycle == get(/databases/$(database)/documents/$(userId)/status).data.number
}
The commented out line works perfectly which means that the {cycle} variable in my path works and the correct number is transferred but when I want to compare the cycle variable with the number out of the databse it doens't work.
Is it possible that I compare strings with numbers or anything like this???
Thanks!!
I could solve it myself. The problems was that I compared a string with a Number. The path delivered by the request as a string which also defines the {cycle} variable as a string. I compared it with my data from my database which was a number...
Solution, convert the number into a string
match /{userId}/test/{cycle}/results {
allow read: if cycle == string(get(/databases/$(database)/documents/$(userId)/status).data.number)
}
For more: https://firebase.google.com/docs/reference/rules/rules.String

URL-parameters input seems inconsistent

I have review multiple instructions on URL-parameters which all suggest 2 approaches:
Parameters can follow / forward slashes or be specified by parameter name and then by parameter value. so either:
1) http://numbersapi.com/42
or
2) http://numbersapi.com/random?min=10&max=20
For the 2nd one, I provide parameter name and then parameter value by using the ?. I also provide multiple parameters using ampersand.
Now I have see the request below which works fine but does not fit into the rules above:
http://numbersapi.com/42?json
I understand that the requests sets 42 as a parameter but why is the ? not followed by the parameter name and just by the value. Also the ? seems to be used as an ampersand???
From Wikipedia:
Every HTTP URL conforms to the syntax of a generic URI. The URI generic syntax consists of a hierarchical sequence of five components:
URI = scheme:[//authority]path[?query][#fragment]
where the authority component divides into three subcomponents:
authority = [userinfo#]host[:port]
This is represented in a syntax diagram as:
As you can see, the ? ends the path part of the URL and starts the query part.
The query part is usually a &-separated string of name=value pairs, but it doesn't have to be, so json is a valid value for the query part.
Or, as the Wikipedia articles says it:
An optional query component preceded by a question mark (?), containing a query string of non-hierarchical data. Its syntax is not well defined, but by convention is most often a sequence of attribute–value pairs separated by a delimiter.
It is also fairly common for request processors to treat a name=value pair that is missing the = sign, as if the it was name=.
E.g. if you're writing Servlet code and call servletRequest.getParameter("json"), it would return an empty string ("") for that last URL in the question.

pdo bind_param containing quote returns nothing

I'm converting a mysqli code into PDO as it was requested but I'm having a hard time trying to pass some single quotes into the new LIKE query.I will only paste the parts regarding this problem as there's no need of pasting the whole query etc I guess.
Whenever I use something like "whatever" it returns the results fine, but when I go for "what'ever" it doesn't return anything... The way I have it at the moment was working with mysqli_ but it doesn't when I changed everything to PDO. Any idea how to actually quote the string or escape it properly?
Thank you in advance.
My variable is
$FilterRaid="%{$_POST['FilterRaid']}%";
The query
$listbugs = $bugtrackerpdo->prepare('
...
INNER JOIN raid ON raid.ID = bugs.Raid
AND raid.RaidName LIKE :raid
...
');
$listbugs->bindParam(':raid', $FilterRaid);
$listbugs->execute();

VisualBasic OleDb accessing Excel spreadsheet, can't set column in query using parameter?

I'm working in Visual Basic and using OleDb to access an Excel spreadsheet. I'm importing the data from the sheet into my DataGridView, and that works fine, but now I'm working on filtering. For the most part it works great, but I'm trying to use parameters ("#p1" and so on), and I'm getting a very strange issue.
I can have the following (excluding a bunch of irrelevant stuff before, in between, and after)
query = query & "Project" & " LIKE #Gah1"
...
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah1", "%House%")
and it gives me the results I'm looking for. But I can't seem to get a parameter for the name of the column itself, for example
query = query & "#Gah1" & " LIKE #Gah2"
...
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah1", "Project")
MyCommand.SelectCommand.Parameters.AddWithValue("#Gah2", "%House%")
does not work (and I've tried enclosing Project in different brackets and stuff in different ways, can't get it to work). I've found plenty of examples on using parameters, but none that use them to give the column name.
I'm guessing the parameter changes how the string is represented, seeing as you don't need to have the ' ' around string literals.
Is it not possible to give column names in parameter? If you can, what do I need to do?
Well it won't let me post comment, so here
a) Oops, no, I guess not
b) The string query that I end up sending in my test query here is
"select * from [Bid Summary$] where #Gah1 LIKE #Gah2"
I can post the procedure if absolutely need be, but it isn't the problem because the whole thing works perfectly fine if I replace #Gah1 with Project or [Project], so I just showed the lines that I change.
I'm very new to parameterized queries, can you explain how to avoid query strings using it? If there's a better way to do what I'm doing I'm happy to use it =)
And thanks for response and edit
I use combination of string methods and parameters, like this:
//replace field name in a query template
query = String.Format("select * from [Bid Summary$] where {0} LIKE ?", "#Gah1");
//set value (name is in OleDb parameter ignored, so it could be null)
MyCommand.SelectCommand.Parameters.AddWithValue(null, "%House%");
Note: There is possibility of a sql injection, so be sure about origin of field name (not from user input).

SQLiteQueryBuilder.buildQuery not using selectArgs?

Alright, I'm trying to query a sqlite database. I was trying to be good and use the query method of SQLiteDatabase and pass in the values in the selectArgs parameter to ensure everything got properly escaped, but it wouldn't work. I never got any rows returned (no errors, either).
I started getting curious about the SQL that this generated so I did some more poking around and found SQLiteQueryBuilder (and apparently Stack Overflow doesn't handle links with parentheses in them well, so I can't link to the anchor for the buildQuery method), which I assume uses the same logic to generate the SQL statement. I did this:
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
builder.setTables(BarcodeDb.Barcodes.TABLE_NAME);
String sql = builder.buildQuery(new String[] { BarcodeDb.Barcodes.ID, BarcodeDb.Barcodes.TIMESTAMP, BarcodeDb.Barcodes.TYPE, BarcodeDb.Barcodes.VALUE },
"? = '?' AND ? = '?'",
new String[] { BarcodeDb.Barcodes.VALUE, barcode.getValue(), BarcodeDb.Barcodes.TYPE, barcode.getType()},
null, null, null, null);
Log.d(tag, "Query is: " + sql);
The SQL that gets logged at this point is:
SELECT _id, timestamp, type, value FROM barcodes WHERE (? = '?' AND ? = '?')
However, here's what the documentation for SQLiteQueryBuilder.buildQuery says about the selectAgs parameter:
You may include ?s in selection, which
will be replaced by the values from
selectionArgs, in order that they
appear in the selection.
...but it isn't working. Any ideas?
The doc for SQLiteQueryBuilder.buildQuery also says, "The values will be bound as Strings." This tells me that it is doing the straight-forward thing, which is writing the SQL leaving the ? parameter markers in place, which is what you are seeing, and binding the selectArgs as input parameters.
The ? are replaced by sqlite when it runs the query, not in the SQL string. The first string in the array will go where you see the first ?, and so on, when the query actually executes. I would expect the logged SQL to still have the ? markers.
Probably, your query fails because you are quoting the ?. For example, don't use WHERE ID = '?', just use WHERE ID = ?, and make sure the selectArgs is a string that satisfies the query.
Two things:
The ? substitution will not be done at this point, but only when the query is executed by the SQLiteDatabase.
From what I've seen, ? substitution only works for the right side of comparison clauses. For example, some people have tried to use ? for the table name, which blows up. I haven't seen anyone try using ? for the left side of the comparison clause, so it might work -- I'm just warning you that it might not.