Changeset View
Changeset View
Standalone View
Standalone View
src/xsprintf/qsprintf.php
| Show All 20 Lines | |||||
| * an "IN" clause. For example: | * an "IN" clause. For example: | ||||
| * | * | ||||
| * qsprintf($escaper, 'WHERE hatID IN (%Ld)', $list_of_hats); | * qsprintf($escaper, 'WHERE hatID IN (%Ld)', $list_of_hats); | ||||
| * | * | ||||
| * %B ("Binary String") | * %B ("Binary String") | ||||
| * Escapes a string for insertion into a pure binary column, ignoring | * Escapes a string for insertion into a pure binary column, ignoring | ||||
| * tests for characters outside of the basic multilingual plane. | * tests for characters outside of the basic multilingual plane. | ||||
| * | * | ||||
| * %C, %LC ("Column") | * %C, %LC, %LK ("Column", "Key Column") | ||||
| * Escapes a column name or a list of column names. | * Escapes a column name or a list of column names. The "%LK" variant | ||||
| * escapes a list of key column specifications which may look like | |||||
| * "column(32)". | |||||
| * | * | ||||
| * %K ("Comment") | * %K ("Comment") | ||||
| * Escapes a comment. | * Escapes a comment. | ||||
| * | * | ||||
| * %Q, %LA, %LO, %LQ, %LJ ("Query Fragment") | * %Q, %LA, %LO, %LQ, %LJ ("Query Fragment") | ||||
| * Injects a query fragment from a prior call to qsprintf(). The list | * Injects a query fragment from a prior call to qsprintf(). The list | ||||
| * variants join a list of query fragments with AND, OR, comma, or space. | * variants join a list of query fragments with AND, OR, comma, or space. | ||||
| * | * | ||||
| * %Z ("Raw Query") | |||||
| * Injects a raw, unescaped query fragment. Dangerous! | |||||
| * | |||||
| * %R ("Database and Table Reference") | * %R ("Database and Table Reference") | ||||
| * Behaves like "%T.%T" and prints a full reference to a table including | * Behaves like "%T.%T" and prints a full reference to a table including | ||||
| * the database. Accepts a AphrontDatabaseTableRefInterface. | * the database. Accepts a AphrontDatabaseTableRefInterface. | ||||
| * | * | ||||
| * %P ("Password or Secret") | * %P ("Password or Secret") | ||||
| * Behaves like "%s", but shows "********" when the query is printed in | * Behaves like "%s", but shows "********" when the query is printed in | ||||
| * logs or traces. Accepts a PhutilOpaqueEnvelope. | * logs or traces. Accepts a PhutilOpaqueEnvelope. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | case 'L': // List of.. | ||||
| $value = implode(', ', $value); | $value = implode(', ', $value); | ||||
| break; | break; | ||||
| case 'C': // ...columns. | case 'C': // ...columns. | ||||
| foreach ($value as $k => $v) { | foreach ($value as $k => $v) { | ||||
| $value[$k] = $escaper->escapeColumnName($v); | $value[$k] = $escaper->escapeColumnName($v); | ||||
| } | } | ||||
| $value = implode(', ', $value); | $value = implode(', ', $value); | ||||
| break; | break; | ||||
| case 'K': // ...key columns. | |||||
| // This is like "%LC", but for escaping column lists passed to key | |||||
| // specifications. These should be escaped as "`column`(123)". For | |||||
| // example: | |||||
| // | |||||
| // ALTER TABLE `x` ADD KEY `y` (`u`(16), `v`(32)); | |||||
| foreach ($value as $k => $v) { | |||||
| $matches = null; | |||||
| if (preg_match('/\((\d+)\)\z/', $v, $matches)) { | |||||
| $v = substr($v, 0, -(strlen($matches[1]) + 2)); | |||||
| $prefix_len = '('.((int)$matches[1]).')'; | |||||
| } else { | |||||
| $prefix_len = ''; | |||||
| } | |||||
| $value[$k] = $escaper->escapeColumnName($v).$prefix_len; | |||||
| } | |||||
amckinleyUnsubmitted Not Done Inline Actionsamckinley: tarnation | |||||
| $value = implode(', ', $value); | |||||
| break; | |||||
| case 'Q': | case 'Q': | ||||
| // TODO: Here, and in "%LO", "%LA", and "%LJ", we should eventually | // TODO: Here, and in "%LO", "%LA", and "%LJ", we should eventually | ||||
| // stop accepting strings. | // stop accepting strings. | ||||
| foreach ($value as $k => $v) { | foreach ($value as $k => $v) { | ||||
| if (is_string($v)) { | if (is_string($v)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| $value[$k] = $v->getUnmaskedString(); | $value[$k] = $v->getUnmaskedString(); | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | switch ($type) { | ||||
| case 'Q': // Query Fragment | case 'Q': // Query Fragment | ||||
| if ($value instanceof PhutilQueryString) { | if ($value instanceof PhutilQueryString) { | ||||
| $value = $value->getUnmaskedString(); | $value = $value->getUnmaskedString(); | ||||
| } | } | ||||
| $type = 's'; | $type = 's'; | ||||
| break; | break; | ||||
| case 'Z': // Raw Query Fragment | |||||
| $type = 's'; | |||||
| break; | |||||
| case '~': // Like Substring | case '~': // Like Substring | ||||
| case '>': // Like Prefix | case '>': // Like Prefix | ||||
| case '<': // Like Suffix | case '<': // Like Suffix | ||||
| $value = $escaper->escapeStringForLikeClause($value); | $value = $escaper->escapeStringForLikeClause($value); | ||||
| switch ($type) { | switch ($type) { | ||||
| case '~': $value = "'%".$value."%'"; break; | case '~': $value = "'%".$value."%'"; break; | ||||
| case '>': $value = "'".$value."%'"; break; | case '>': $value = "'".$value."%'"; break; | ||||
| case '<': $value = "'%".$value."'"; break; | case '<': $value = "'%".$value."'"; break; | ||||
| ▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | function xsprintf_query($userdata, &$pattern, &$pos, &$value, &$length) { | ||||
| $pattern[$pos] = $type; | $pattern[$pos] = $type; | ||||
| } | } | ||||
| function qsprintf_check_type($value, $type, $query) { | function qsprintf_check_type($value, $type, $query) { | ||||
| switch ($type) { | switch ($type) { | ||||
| case 'Ld': | case 'Ld': | ||||
| case 'Ls': | case 'Ls': | ||||
| case 'LC': | case 'LC': | ||||
| case 'LK': | |||||
| case 'LB': | case 'LB': | ||||
| case 'Lf': | case 'Lf': | ||||
| case 'LQ': | case 'LQ': | ||||
| case 'LA': | case 'LA': | ||||
| case 'LO': | case 'LO': | ||||
| case 'LJ': | case 'LJ': | ||||
| if (!is_array($value)) { | if (!is_array($value)) { | ||||
| throw new AphrontParameterQueryException( | throw new AphrontParameterQueryException( | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | case 'Q': | ||||
| if (!($value instanceof PhutilQueryString)) { | if (!($value instanceof PhutilQueryString)) { | ||||
| throw new AphrontParameterQueryException( | throw new AphrontParameterQueryException( | ||||
| $query, | $query, | ||||
| pht('Expected a PhutilQueryString for %%%s conversion.', $type)); | pht('Expected a PhutilQueryString for %%%s conversion.', $type)); | ||||
| } | } | ||||
| break; | break; | ||||
| case 'Z': | |||||
| if (!is_string($value)) { | |||||
| throw new AphrontParameterQueryException( | |||||
| $query, | |||||
| pht('Value for "%%Z" conversion should be a raw string.')); | |||||
| } | |||||
| break; | |||||
| case 'LC': | case 'LC': | ||||
| case 'LK': | |||||
| case 'T': | case 'T': | ||||
| case 'C': | case 'C': | ||||
| if (!is_string($value)) { | if (!is_string($value)) { | ||||
| throw new AphrontParameterQueryException( | throw new AphrontParameterQueryException( | ||||
| $query, | $query, | ||||
| pht('Expected a string for %%%s conversion.', $type)); | pht('Expected a string for %%%s conversion.', $type)); | ||||
| } | } | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 51 Lines • Show Last 20 Lines | |||||