]> granicus.if.org Git - php/commitdiff
Fixed bug #71998 Function pg_insert does not insert when column type = inet
authorAnatol Belski <ab@php.net>
Sun, 10 Apr 2016 16:48:35 +0000 (18:48 +0200)
committerAnatol Belski <ab@php.net>
Sun, 10 Apr 2016 16:48:35 +0000 (18:48 +0200)
ext/pgsql/pgsql.c
ext/pgsql/tests/bug71998.phpt [new file with mode: 0644]

index cb6f4cac4934d7a1af9d85acf4d7ea17005662fa..21321e4a95ed910c661ae99f8701e78ac41f2fb5 100644 (file)
@@ -6145,8 +6145,11 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
                                                        ZVAL_STRINGL(&new_val, "NULL", sizeof("NULL")-1);
                                                }
                                                else {
-                                                       /* better regex? IPV6 and IPV4 */
-                                                       if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$", 0) == FAILURE) {
+                                                       /* The inet type holds an IPv4 or IPv6 host address, and optionally its subnet, all in one field. See more in the doc.
+                                                               The regex might still be not perfect, but catches the most of IP variants. We might decide to remove the regex
+                                                               at all though and let the server side to handle it.*/
+                                                       if (php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])(\/[0-9]{1,3})?$", 0) == FAILURE
+                                                               && php_pgsql_convert_match(Z_STRVAL_P(val), Z_STRLEN_P(val), "^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))(\/[0-9]{1,3})?$", 0) == FAILURE) {
                                                                err = 1;
                                                        }
                                                        else {
@@ -6165,7 +6168,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
                                }
                                PGSQL_CONV_CHECK_IGNORE();
                                if (err) {
-                                       php_error_docref(NULL, E_NOTICE, "Expects NULL or string for '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
+                                       php_error_docref(NULL, E_NOTICE, "Expects NULL or IPv4 or IPv6 address string for '%s' (%s)", Z_STRVAL_P(type), ZSTR_VAL(field));
                                }
                                break;
 
diff --git a/ext/pgsql/tests/bug71998.phpt b/ext/pgsql/tests/bug71998.phpt
new file mode 100644 (file)
index 0000000..b992416
--- /dev/null
@@ -0,0 +1,196 @@
+--TEST--
+Bug #71998 Function pg_insert does not insert when column type = inet
+--SKIPIF--
+<?php include("skipif.inc"); ?>
+--FILE--
+<?php
+// Kudos for the IP regex to 
+// http://stackoverflow.com/a/17871737/3358424
+
+include('config.inc');
+
+$db = pg_connect($conn_str);
+
+pg_query("CREATE TABLE tmp_statistics (id integer NOT NULL, remote_addr inet);");
+
+$ips = array(
+       /* IPv4*/
+       "127.0.0.1",
+       "10.0.0.1",
+       "192.168.1.1",
+       "0.0.0.0",
+       "255.255.255.255",
+       "192.168.1.35/24",
+
+       /* IPv6 */
+       "::1",
+       "::10.2.3.4",
+       "::ffff:10.4.3.2",
+       "1:2:3:4:5:6:7:8",
+       "::ffff:10.0.0.1",
+       "::ffff:1.2.3.4",
+       "::ffff:0.0.0.0",
+       "1:2:3:4:5:6:77:88",
+       "::ffff:255.255.255.255",
+       "fe08::7:8",
+       "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff",
+       "::5:aef1:ffff/128",
+       "2001:4f8:3:ba::/112",
+
+);
+
+$bad = array(
+       /* bad */
+       "256.257.258.259",
+       "fe08::7:8interface",
+       "schnitzel",
+       "10002.3.4",
+       "1.2.3.4.5",
+       "256.0.0.0",
+       "260.0.0.0",
+);
+
+$ips = array_merge($ips, $bad);
+$i = 0;
+$errors = 0;
+foreach ($ips as $ip) {
+       $data = array("id" => ++$i, "remote_addr" => $ip);
+       $r = @pg_insert($db, 'tmp_statistics', $data);   
+
+       if (!$r && in_array($ip, $bad)) {
+               $errors++;
+               //echo pg_last_error($db);
+       }
+
+       //pg_query($db, "INSERT INTO tmp_statistics (id, remote_addr) VALUES (2, '127.0.0.1')"); // OK, record inserted
+}
+
+
+$r = pg_query($db, "SELECT * FROM tmp_statistics");
+while (false != ($row = pg_fetch_row($r))) {
+       var_dump($row);
+}
+echo $errors, " errors catched\n";
+
+pg_query($db, "DROP TABLE tmp_statistics");
+pg_close($db);
+
+?>
+==DONE==
+--EXPECT--
+array(2) {
+  [0]=>
+  string(1) "1"
+  [1]=>
+  string(9) "127.0.0.1"
+}
+array(2) {
+  [0]=>
+  string(1) "2"
+  [1]=>
+  string(8) "10.0.0.1"
+}
+array(2) {
+  [0]=>
+  string(1) "3"
+  [1]=>
+  string(11) "192.168.1.1"
+}
+array(2) {
+  [0]=>
+  string(1) "4"
+  [1]=>
+  string(7) "0.0.0.0"
+}
+array(2) {
+  [0]=>
+  string(1) "5"
+  [1]=>
+  string(15) "255.255.255.255"
+}
+array(2) {
+  [0]=>
+  string(1) "6"
+  [1]=>
+  string(15) "192.168.1.35/24"
+}
+array(2) {
+  [0]=>
+  string(1) "7"
+  [1]=>
+  string(3) "::1"
+}
+array(2) {
+  [0]=>
+  string(1) "8"
+  [1]=>
+  string(10) "::10.2.3.4"
+}
+array(2) {
+  [0]=>
+  string(1) "9"
+  [1]=>
+  string(15) "::ffff:10.4.3.2"
+}
+array(2) {
+  [0]=>
+  string(2) "10"
+  [1]=>
+  string(15) "1:2:3:4:5:6:7:8"
+}
+array(2) {
+  [0]=>
+  string(2) "11"
+  [1]=>
+  string(15) "::ffff:10.0.0.1"
+}
+array(2) {
+  [0]=>
+  string(2) "12"
+  [1]=>
+  string(14) "::ffff:1.2.3.4"
+}
+array(2) {
+  [0]=>
+  string(2) "13"
+  [1]=>
+  string(14) "::ffff:0.0.0.0"
+}
+array(2) {
+  [0]=>
+  string(2) "14"
+  [1]=>
+  string(17) "1:2:3:4:5:6:77:88"
+}
+array(2) {
+  [0]=>
+  string(2) "15"
+  [1]=>
+  string(22) "::ffff:255.255.255.255"
+}
+array(2) {
+  [0]=>
+  string(2) "16"
+  [1]=>
+  string(9) "fe08::7:8"
+}
+array(2) {
+  [0]=>
+  string(2) "17"
+  [1]=>
+  string(39) "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
+}
+array(2) {
+  [0]=>
+  string(2) "18"
+  [1]=>
+  string(13) "::5:aef1:ffff"
+}
+array(2) {
+  [0]=>
+  string(2) "19"
+  [1]=>
+  string(19) "2001:4f8:3:ba::/112"
+}
+7 errors catched
+==DONE==