|
23 | 23 | #include "ext/standard/info.h"
|
24 | 24 | #include "pdo/php_pdo.h"
|
25 | 25 | #include "pdo/php_pdo_driver.h"
|
| 26 | +/* this file actually lives in main/ */ |
| 27 | +#include "php_odbc_utils.h" |
26 | 28 | #include "php_pdo_odbc.h"
|
27 | 29 | #include "php_pdo_odbc_int.h"
|
28 | 30 | #include "zend_exceptions.h"
|
@@ -428,97 +430,6 @@ static const struct pdo_dbh_methods odbc_methods = {
|
428 | 430 | NULL /* get_gc */
|
429 | 431 | };
|
430 | 432 |
|
431 |
| -/** |
432 |
| - * Determines if a string matches the ODBC quoting rules. |
433 |
| - * |
434 |
| - * A valid quoted string begins with a '{', ends with a '}', and has no '}' |
435 |
| - * inside of the string that aren't repeated (as to be escaped). |
436 |
| - * |
437 |
| - * These rules are what .NET also follows. |
438 |
| - */ |
439 |
| -static bool is_odbc_quoted(const char *str) |
440 |
| -{ |
441 |
| - if (!str) { |
442 |
| - return false; |
443 |
| - } |
444 |
| - /* ODBC quotes are curly braces */ |
445 |
| - if (str[0] != '{') { |
446 |
| - return false; |
447 |
| - } |
448 |
| - /* Check for } that aren't doubled up or at the end of the string */ |
449 |
| - size_t length = strlen(str); |
450 |
| - for (size_t i = 0; i < length; i++) { |
451 |
| - if (str[i] == '}' && str[i + 1] == '}') { |
452 |
| - /* Skip over so we don't count it again */ |
453 |
| - i++; |
454 |
| - } else if (str[i] == '}' && str[i + 1] != '\0') { |
455 |
| - /* If not at the end, not quoted */ |
456 |
| - return false; |
457 |
| - } |
458 |
| - } |
459 |
| - return true; |
460 |
| -} |
461 |
| - |
462 |
| -/** |
463 |
| - * Determines if a value for a connection string should be quoted. |
464 |
| - * |
465 |
| - * The ODBC specification mentions: |
466 |
| - * "Because of connection string and initialization file grammar, keywords and |
467 |
| - * and attribute values that contain the characters []{}(),;?*=!@ not enclosed |
468 |
| - * with braces should be avoided." |
469 |
| - * |
470 |
| - * Note that it assumes that the string is *not* already quoted. You should |
471 |
| - * check beforehand. |
472 |
| - */ |
473 |
| -static bool should_odbc_quote(const char *str) |
474 |
| -{ |
475 |
| - return strpbrk(str, "[]{}(),;?*=!@") != NULL; |
476 |
| -} |
477 |
| - |
478 |
| -/** |
479 |
| - * Estimates the worst-case scenario for a quoted version of a string's size. |
480 |
| - */ |
481 |
| -static size_t estimate_odbc_quote_length(const char *in_str) |
482 |
| -{ |
483 |
| - /* Assume all '}'. Include '{,' '}', and the null terminator too */ |
484 |
| - return (strlen(in_str) * 2) + 3; |
485 |
| -} |
486 |
| - |
487 |
| -/** |
488 |
| - * Quotes a string with ODBC rules. |
489 |
| - * |
490 |
| - * Some characters (curly braces, semicolons) are special and must be quoted. |
491 |
| - * In the case of '}' in a quoted string, they must be escaped SQL style; that |
492 |
| - * is, repeated. |
493 |
| - */ |
494 |
| -static size_t odbc_quote(char *out_str, const char *in_str, size_t out_str_size) |
495 |
| -{ |
496 |
| - *out_str++ = '{'; |
497 |
| - out_str_size--; |
498 |
| - while (out_str_size > 2) { |
499 |
| - if (*in_str == '\0') { |
500 |
| - break; |
501 |
| - } else if (*in_str == '}' && out_str_size - 1 > 2) { |
502 |
| - /* enough room to append */ |
503 |
| - *out_str++ = '}'; |
504 |
| - *out_str++ = *in_str++; |
505 |
| - out_str_size -= 2; |
506 |
| - } else if (*in_str == '}') { |
507 |
| - /* not enough, truncate here */ |
508 |
| - break; |
509 |
| - } else { |
510 |
| - *out_str++ = *in_str++; |
511 |
| - out_str_size--; |
512 |
| - } |
513 |
| - } |
514 |
| - /* append termination */ |
515 |
| - *out_str++ = '}'; |
516 |
| - *out_str++ = '\0'; |
517 |
| - out_str_size -= 2; |
518 |
| - /* return how many characters were left */ |
519 |
| - return strlen(in_str); |
520 |
| -} |
521 |
| - |
522 | 433 | static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ */
|
523 | 434 | {
|
524 | 435 | pdo_odbc_db_handle *H;
|
@@ -584,28 +495,28 @@ static int pdo_odbc_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{
|
584 | 495 | && !strstr(dbh->data_source, "PWD=");
|
585 | 496 | if (is_uid_set && is_pwd_set) {
|
586 | 497 | char *uid = NULL, *pwd = NULL;
|
587 |
| - bool should_quote_uid = !is_odbc_quoted(dbh->username) && should_odbc_quote(dbh->username); |
588 |
| - bool should_quote_pwd = !is_odbc_quoted(dbh->password) && should_odbc_quote(dbh->password); |
| 498 | + bool should_quote_uid = !php_odbc_connstr_is_quoted(dbh->username) && php_odbc_connstr_should_quote(dbh->username); |
| 499 | + bool should_quote_pwd = !php_odbc_connstr_is_quoted(dbh->password) && php_odbc_connstr_should_quote(dbh->password); |
589 | 500 | bool connection_string_fail = false;
|
590 | 501 | if (should_quote_uid) {
|
591 |
| - size_t estimated_length = estimate_odbc_quote_length(dbh->username); |
| 502 | + size_t estimated_length = php_odbc_connstr_estimate_quote_length(dbh->username); |
592 | 503 | uid = emalloc(estimated_length);
|
593 | 504 | if (!uid) {
|
594 | 505 | connection_string_fail = true;
|
595 | 506 | goto connection_string_fail;
|
596 | 507 | }
|
597 |
| - odbc_quote(uid, dbh->username, estimated_length); |
| 508 | + php_odbc_connstr_quote(uid, dbh->username, estimated_length); |
598 | 509 | } else {
|
599 | 510 | uid = dbh->username;
|
600 | 511 | }
|
601 | 512 | if (should_quote_pwd) {
|
602 |
| - size_t estimated_length = estimate_odbc_quote_length(dbh->password); |
| 513 | + size_t estimated_length = php_odbc_connstr_estimate_quote_length(dbh->password); |
603 | 514 | pwd = emalloc(estimated_length);
|
604 | 515 | if (!pwd) {
|
605 | 516 | connection_string_fail = true;
|
606 | 517 | goto connection_string_fail;
|
607 | 518 | }
|
608 |
| - odbc_quote(pwd, dbh->password, estimated_length); |
| 519 | + php_odbc_connstr_quote(pwd, dbh->password, estimated_length); |
609 | 520 | } else {
|
610 | 521 | pwd = dbh->password;
|
611 | 522 | }
|
|
0 commit comments