Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/extended escapes #7

Merged
merged 7 commits into from
Mar 29, 2023
Merged

Feat/extended escapes #7

merged 7 commits into from
Mar 29, 2023

Conversation

gwillz
Copy link
Collaborator

@gwillz gwillz commented Mar 29, 2023

A common issue we've found with the query builder is the lack of escapes within string conditions and functions. This means we can't reliably identify column/table names in order to effectively quote them.

So this feature implements a "post effect" within the query builder that extracts and replaces any matching table 'identifiers' registered with the query object, i.e. from + join tables. It's surprisingly effective and gives us a small edge on safety.

This feature is actually ripped directly from Chris' work here. Fingers crossed he's cool with that ;)

It's important to remember that is a syntax safety feature, not a user-input sanitizing feature. Field names must always be explicitly validated if they come from an untrusted source.

Example

As seen in the tests (w/ sqlite quoting rules).

$query = $this->pdb->find('stuff')
        ->innerJoin('more as mmm', ['~stuff.id = mmm.stuff_id'])
        ->select([
            'count(~stuff.id)',
            'max(missing.count)',
            'min(~also.count)',
        ]);

From this query the identifier are:

  • stuff
  • mmm (aliased from more)

Without quoting.
Note that prefixes, aliases, and buildClause() still perform their usual quoting rules.

SELECT count(pdb_stuff.id), max(missing.count), min(pdb_also.count)
FROM "pdb_stuff"
INNER JOIN "pdb_more" AS "mmm"
ON pdb_stuff.id = mmm.stuff_id

With quoting.
Note that missing.count is ignored because it's not a registered table identifier. That said, the query would fail anyway.

SELECT count("pdb_stuff"."id"), max(missing.count), min("pdb_also"."count")
FROM "pdb_stuff" 
INNER JOIN "pdb_more" AS "mmm"
ON "pdb_stuff"."id" = "mmm"."stuff_id"

@aitken85 aitken85 merged commit ca2981d into master Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants