del php-src: NEWS configure.in ext/fileinfo/libmagic.patch ext/fileinfo/libmagic/ascmagic.c ext/fileinfo/libmagic/file.h ext/fileinfo/libmagic/funcs.c
ext/fileinfo/libmagic/softmagic.c ext/fileinfo/php_fileinfo.h ext/fileinfo/tests/cve-20 14-1943.phpt ext/json/json.c ext/json/php _json.h
ext/openssl/openssl.c ext/pgsql/pgsql.c e xt/pgsql/php_pgsql.h main/php_version.h
| From: | Ferenc Kovacs | Date: | Wed, 19 Feb 2014 07:50:24 +0000 |
| Subject: | del php-src: NEWS configure.in ext/fileinfo/libmagic.patch ext/fileinfo/libmagic/ascmagic.c ext/fileinfo/libmagic/file.h ext/fileinfo/libmagic/funcs.c ext/fileinfo/libmagic/softmagic.c ext/fileinfo/php_fileinfo.h ext/fileinfo/tests/cve-20 14-1943.phpt ext/json/json.c ext/json/php _json.h ext/openssl/openssl.c ext/pgsql/pgsql.c e xt/pgsql/php_pgsql.h main/php_version.h |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-76108@lists.php.net to get a copy of this message | ||
Branch: PHP-5.5
Deleted commits count: 7
User: Ferenc Kovacs <tyrael@php.net> Wed, 19 Feb 2014 07:50:24 +0000
Changed paths:
M NEWS
M configure.in
M ext/fileinfo/libmagic.patch
M ext/fileinfo/libmagic/ascmagic.c
M ext/fileinfo/libmagic/file.h
M ext/fileinfo/libmagic/funcs.c
M ext/fileinfo/libmagic/softmagic.c
M ext/fileinfo/php_fileinfo.h
A ext/fileinfo/tests/cve-2014-1943.phpt
M ext/json/json.c
M ext/json/php_json.h
M ext/openssl/openssl.c
M ext/pgsql/pgsql.c
M ext/pgsql/php_pgsql.h
M main/php_version.h
diff --git b/NEWS a/NEWS index f1a02ee..32000e2 100644 --- b/NEWS +++ a/NEWS @@ -1,5 +1,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +?? ??? 2014, PHP 5.5.11 + ?? ??? 2014, PHP 5.5.10 - Core: @@ -9,6 +11,13 @@ PHP NEWS . Fixed bug #45528 (Allow the DateTimeZone constructor to accept timezones per offset too). (Derick) +- Fileinfo: + . Bug #66731 (file: infinite recursion) (CVE-2014-1943). (Remi) + +- JSON: + . Fixed bug #65753 (JsonSerializeable couldn't implement on module extension) + (chobieeee@php.net) + - LDAP: . Implemented ldap_modify_batch (https://wiki.php.net/rfc/ldap_modify_batch). (Ondřej Hošek) @@ -20,6 +29,11 @@ PHP NEWS - PCRE: . Upgraded to PCRE 8.34. (Anatol) +- Pgsql: + . Added warning for dangerous client encoding and remove possible injections + for pg_insert()/pg_update()/pg_delete()/pg_select(). (Yasuo) + + 06 Feb 2014, PHP 5.5.9 - Core: diff --git b/configure.in a/configure.in index 1f4080f..13ff75d 100644 --- b/configure.in +++ a/configure.in @@ -119,7 +119,7 @@ int zend_sprintf(char *buffer, const char *format, ...); PHP_MAJOR_VERSION=5 PHP_MINOR_VERSION=5 -PHP_RELEASE_VERSION=9 +PHP_RELEASE_VERSION=11 PHP_EXTRA_VERSION="-dev" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION` diff --git b/ext/fileinfo/libmagic.patch a/ext/fileinfo/libmagic.patch index 97e771e..d7fc532 100644 --- b/ext/fileinfo/libmagic.patch +++ a/ext/fileinfo/libmagic.patch @@ -1,6 +1,6 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c ---- libmagic.orig/apprentice.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/apprentice.c 2013-04-27 13:53:32.175250261 +0200 +--- libmagic.orig/apprentice.c Thu Mar 21 18:45:14 2013 ++++ libmagic/apprentice.c Fri May 3 15:19:35 2013 @@ -29,6 +29,8 @@ * apprentice - make one pass through /etc/magic, learning its secrets. */ @@ -830,8 +830,8 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c m->str_flags = swap4(m->str_flags); } diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c ---- libmagic.orig/ascmagic.c 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/ascmagic.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/ascmagic.c Wed Oct 31 18:03:01 2012 ++++ libmagic/ascmagic.c Tue Feb 18 18:44:17 2014 @@ -139,7 +139,7 @@ /* malloc size is a conservative overestimate; could be improved, or at least realloced after conversion. */ @@ -841,6 +841,15 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c file_oomem(ms, mlen); goto done; } +@@ -147,7 +147,7 @@ + == NULL) + goto done; + if ((rv = file_softmagic(ms, utf8_buf, +- (size_t)(utf8_end - utf8_buf), TEXTTEST, text)) == 0) ++ (size_t)(utf8_end - utf8_buf), 0, TEXTTEST, text)) == 0) + rv = -1; + } + @@ -211,6 +211,7 @@ case 0: if (file_printf(ms, ", ") == -1) @@ -860,8 +869,8 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c return rv; } diff -u libmagic.orig/cdf.c libmagic/cdf.c ---- libmagic.orig/cdf.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/cdf.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/cdf.c Thu Mar 21 18:45:14 2013 ++++ libmagic/cdf.c Sun Apr 7 22:30:22 2013 @@ -43,7 +43,17 @@ #include <err.h> #endif @@ -923,8 +932,8 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c (void)fprintf(stderr, "timestamp %s\n", buf); } else { diff -u libmagic.orig/cdf.h libmagic/cdf.h ---- libmagic.orig/cdf.h 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/cdf.h 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/cdf.h Wed Oct 31 18:03:01 2012 ++++ libmagic/cdf.h Sun Apr 7 22:30:22 2013 @@ -35,10 +35,12 @@ #ifndef _H_CDF_ #define _H_CDF_ @@ -966,8 +975,8 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h void cdf_swap_header(cdf_header_t *); void cdf_unpack_header(cdf_header_t *, char *); diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c ---- libmagic.orig/cdf_time.c 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/cdf_time.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/cdf_time.c Wed Oct 31 18:03:01 2012 ++++ libmagic/cdf_time.c Sun Apr 7 22:30:22 2013 @@ -96,7 +96,7 @@ } @@ -1026,8 +1035,8 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL; static const char *ref = "Sat Apr 23 01:30:00 1977"; diff -u libmagic.orig/compress.c libmagic/compress.c ---- libmagic.orig/compress.c 2013-01-06 21:35:43.000000000 +0100 -+++ libmagic/compress.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/compress.c Sun Jan 6 21:35:43 2013 ++++ libmagic/compress.c Sun Apr 7 22:30:22 2013 @@ -32,6 +32,7 @@ * uncompress(method, old, n, newch) - uncompress old into new, * using method, return sizeof new @@ -1189,8 +1198,8 @@ diff -u libmagic.orig/compress.c libmagic/compress.c -#endif +#endif /* if PHP_FILEINFO_UNCOMPRESS */ diff -u libmagic.orig/file.h libmagic/file.h ---- libmagic.orig/file.h 2013-02-18 16:40:59.000000000 +0100 -+++ libmagic/file.h 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/file.h Mon Feb 18 16:40:59 2013 ++++ libmagic/file.h Tue Feb 18 18:44:17 2014 @@ -33,11 +33,9 @@ #ifndef __file_h__ #define __file_h__ @@ -1303,7 +1312,13 @@ diff -u libmagic.orig/file.h libmagic/file.h protected int file_zmagic(struct magic_set *, int, const char *, const unsigned char *, size_t); #endif -@@ -443,16 +442,13 @@ +@@ -438,21 +437,18 @@ + unichar **, size_t *, const char **, const char **, const char **); + protected int file_is_tar(struct magic_set *, const unsigned char *, size_t); + protected int file_softmagic(struct magic_set *, const unsigned char *, size_t, +- int, int); ++ size_t, int, int); + protected int file_apprentice(struct magic_set *, const char *, int); protected int file_magicfind(struct magic_set *, const char *, struct mlist *); protected uint64_t file_signextend(struct magic_set *, struct magic *, uint64_t); @@ -1377,22 +1392,24 @@ diff -u libmagic.orig/file.h libmagic/file.h #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK) #define QUICK -@@ -533,4 +511,12 @@ - #define FILE_RCSID(id) +@@ -531,6 +509,14 @@ #endif - + #else + #define FILE_RCSID(id) ++#endif ++ +#ifdef PHP_WIN32 +#define FINFO_LSEEK_FUNC _lseek +#define FINFO_READ_FUNC _read +#else +#define FINFO_LSEEK_FUNC lseek +#define FINFO_READ_FUNC read -+#endif -+ + #endif + #endif /* __file_h__ */ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c ---- libmagic.orig/fsmagic.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/fsmagic.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/fsmagic.c Thu Mar 21 18:45:14 2013 ++++ libmagic/fsmagic.c Sun Apr 7 22:30:22 2013 @@ -59,27 +59,21 @@ # define minor(dev) ((dev) & 0xff) #endif @@ -1758,8 +1775,8 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c return ret; } diff -u libmagic.orig/funcs.c libmagic/funcs.c ---- libmagic.orig/funcs.c 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/funcs.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/funcs.c Wed Oct 31 18:03:01 2012 ++++ libmagic/funcs.c Tue Feb 18 18:44:17 2014 @@ -41,52 +41,42 @@ #if defined(HAVE_WCTYPE_H) #include <wctype.h> @@ -1896,7 +1913,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "zmagic %d\n", m); goto done; -@@ -219,12 +221,17 @@ +@@ -219,16 +221,21 @@ } /* Check if we have a CDF file */ @@ -1919,6 +1936,11 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c /* try soft magic tests */ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) +- if ((m = file_softmagic(ms, ubuf, nb, BINTEST, ++ if ((m = file_softmagic(ms, ubuf, nb, 0, BINTEST, + looks_text)) != 0) { + if ((ms->flags & MAGIC_DEBUG) != 0) + (void)fprintf(stderr, "softmagic %d\n", m); @@ -296,7 +303,6 @@ return m; @@ -2047,8 +2069,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c } + diff -u libmagic.orig/magic.c libmagic/magic.c ---- libmagic.orig/magic.c 2013-01-11 17:43:09.000000000 +0100 -+++ libmagic/magic.c 2013-04-27 13:53:32.175250261 +0200 +--- libmagic.orig/magic.c Fri Jan 11 17:43:09 2013 ++++ libmagic/magic.c Fri May 3 15:19:35 2013 @@ -25,11 +25,6 @@ * SUCH DAMAGE. */ @@ -2391,8 +2413,8 @@ diff -u libmagic.orig/magic.c libmagic/magic.c public const char * magic_error(struct magic_set *ms) diff -u libmagic.orig/magic.h libmagic/magic.h ---- libmagic.orig/magic.h 2013-03-21 18:52:42.000000000 +0100 -+++ libmagic/magic.h 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/magic.h Thu Mar 21 18:52:42 2013 ++++ libmagic/magic.h Sun Apr 7 22:30:22 2013 @@ -87,6 +87,7 @@ const char *magic_getpath(const char *, int); @@ -2410,15 +2432,15 @@ diff -u libmagic.orig/magic.h libmagic/magic.h int magic_errno(magic_t); diff -u libmagic.orig/print.c libmagic/print.c ---- libmagic.orig/print.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/print.c 2013-04-27 13:53:32.175250261 +0200 -@@ -28,13 +28,17 @@ - /* +--- libmagic.orig/print.c Thu Mar 21 18:45:14 2013 ++++ libmagic/print.c Mon Dec 16 23:09:24 2013 +@@ -29,12 +29,17 @@ * print.c - debugging printout routines */ + +#define _GNU_SOURCE +#include "php.h" - ++ #include "file.h" +#include "cdf.h" @@ -2430,7 +2452,7 @@ diff -u libmagic.orig/print.c libmagic/print.c #include <string.h> #include <stdarg.h> #include <stdlib.h> -@@ -43,188 +47,28 @@ +@@ -43,188 +48,28 @@ #endif #include <time.h> @@ -2631,7 +2653,7 @@ diff -u libmagic.orig/print.c libmagic/print.c } protected const char * -@@ -235,7 +79,7 @@ +@@ -235,7 +80,7 @@ struct tm *tm; if (flags & FILE_T_WINDOWS) { @@ -2641,8 +2663,8 @@ diff -u libmagic.orig/print.c libmagic/print.c t = ts.tv_sec; } diff -u libmagic.orig/readcdf.c libmagic/readcdf.c ---- libmagic.orig/readcdf.c 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/readcdf.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/readcdf.c Wed Oct 31 18:03:01 2012 ++++ libmagic/readcdf.c Sun Apr 7 22:30:22 2013 @@ -30,7 +30,11 @@ #endif @@ -2704,8 +2726,8 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c if (file_printf(ms, "application/CDFV2-corrupt") == -1) return -1; diff -u libmagic.orig/readelf.c libmagic/readelf.c ---- libmagic.orig/readelf.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/readelf.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/readelf.c Thu Mar 21 18:45:14 2013 ++++ libmagic/readelf.c Sun Apr 7 22:30:22 2013 @@ -48,8 +48,8 @@ private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t, off_t, int *, int); @@ -2956,8 +2978,8 @@ diff -u libmagic.orig/readelf.c libmagic/readelf.c if (fstat(fd, &st) == -1) { diff -u libmagic.orig/readelf.h libmagic/readelf.h ---- libmagic.orig/readelf.h 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/readelf.h 2013-03-31 16:57:18.499744030 +0200 +--- libmagic.orig/readelf.h Thu Mar 21 18:45:14 2013 ++++ libmagic/readelf.h Wed Mar 28 15:35:26 2012 @@ -44,9 +44,17 @@ typedef uint32_t Elf32_Word; typedef uint8_t Elf32_Char; @@ -2977,8 +2999,8 @@ diff -u libmagic.orig/readelf.h libmagic/readelf.h typedef uint32_t Elf64_Word; typedef uint8_t Elf64_Char; diff -u libmagic.orig/softmagic.c libmagic/softmagic.c ---- libmagic.orig/softmagic.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/softmagic.c 2013-05-14 11:00:07.044745939 +0200 +--- libmagic.orig/softmagic.c Thu Mar 21 18:45:14 2013 ++++ libmagic/softmagic.c Tue Feb 18 18:44:17 2014 @@ -41,6 +41,11 @@ #include <stdlib.h> #include <time.h> @@ -2991,6 +3013,22 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c private int match(struct magic_set *, struct magic *, uint32_t, const unsigned char *, size_t, size_t, int, int, int, int, int *, int *, +@@ -69,13 +74,13 @@ + /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ + protected int + file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, +- int mode, int text) ++ size_t level, int mode, int text) + { + struct mlist *ml; + int rv, printed_something = 0, need_separator = 0; + for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) + if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode, +- text, 0, 0, &printed_something, &need_separator, ++ text, 0, level, &printed_something, &need_separator, + NULL)) != 0) + return rv; + @@ -132,7 +137,7 @@ struct magic *m = &magic[magindex]; @@ -3113,7 +3151,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } if (m->flag & INDIR) { -@@ -1644,9 +1624,6 @@ +@@ -1644,16 +1624,13 @@ if ((ms->flags & MAGIC_DEBUG) != 0) { mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); @@ -3123,7 +3161,32 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } } -@@ -1717,12 +1694,12 @@ + /* Verify we have enough data to match magic type */ + switch (m->type) { + case FILE_BYTE: +- if (nbytes < (offset + 1)) /* should alway be true */ ++ if (nbytes < (offset + 1)) /* should always be true */ + return 0; + break; + +@@ -1703,6 +1680,8 @@ + break; + + case FILE_INDIRECT: ++ if (offset == 0) ++ return 0; + if (nbytes < offset) + return 0; + sbuf = ms->o.buf; +@@ -1710,19 +1689,19 @@ + ms->o.buf = NULL; + ms->offset = 0; + rv = file_softmagic(ms, s + offset, nbytes - offset, +- BINTEST, text); ++ recursion_level, BINTEST, text); + if ((ms->flags & MAGIC_DEBUG) != 0) + fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); + rbuf = ms->o.buf; ms->o.buf = sbuf; ms->offset = soffset; if (rv == 1) { @@ -3139,7 +3202,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } return rv; -@@ -1837,6 +1814,42 @@ +@@ -1837,6 +1816,42 @@ return file_strncmp(a, b, len, flags); } @@ -3182,7 +3245,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c private int magiccheck(struct magic_set *ms, struct magic *m) { -@@ -1996,69 +2009,157 @@ +@@ -1996,69 +2011,157 @@ break; } case FILE_REGEX: { diff --git b/ext/fileinfo/libmagic/ascmagic.c a/ext/fileinfo/libmagic/ascmagic.c index 2090097..c0041df 100644 --- b/ext/fileinfo/libmagic/ascmagic.c +++ a/ext/fileinfo/libmagic/ascmagic.c @@ -147,7 +147,7 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, == NULL) goto done; if ((rv = file_softmagic(ms, utf8_buf, - (size_t)(utf8_end - utf8_buf), TEXTTEST, text)) == 0) + (size_t)(utf8_end - utf8_buf), 0, TEXTTEST, text)) == 0) rv = -1; } diff --git b/ext/fileinfo/libmagic/file.h a/ext/fileinfo/libmagic/file.h index 19b6872..ab5082d 100644 --- b/ext/fileinfo/libmagic/file.h +++ a/ext/fileinfo/libmagic/file.h @@ -437,7 +437,7 @@ protected int file_encoding(struct magic_set *, const unsigned char *, size_t, unichar **, size_t *, const char **, const char **, const char **); protected int file_is_tar(struct magic_set *, const unsigned char *, size_t); protected int file_softmagic(struct magic_set *, const unsigned char *, size_t, - int, int); + size_t, int, int); protected int file_apprentice(struct magic_set *, const char *, int); protected int file_magicfind(struct magic_set *, const char *, struct mlist *); protected uint64_t file_signextend(struct magic_set *, struct magic *, diff --git b/ext/fileinfo/libmagic/funcs.c a/ext/fileinfo/libmagic/funcs.c index 9c0d2bd..011ca42 100644 --- b/ext/fileinfo/libmagic/funcs.c +++ a/ext/fileinfo/libmagic/funcs.c @@ -235,7 +235,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const /* try soft magic tests */ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) - if ((m = file_softmagic(ms, ubuf, nb, BINTEST, + if ((m = file_softmagic(ms, ubuf, nb, 0, BINTEST, looks_text)) != 0) { if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "softmagic %d\n", m); diff --git b/ext/fileinfo/libmagic/softmagic.c a/ext/fileinfo/libmagic/softmagic.c index 0671fa9..7c5f628 100644 --- b/ext/fileinfo/libmagic/softmagic.c +++ a/ext/fileinfo/libmagic/softmagic.c @@ -74,13 +74,13 @@ private void cvt_64(union VALUETYPE *, const struct magic *); /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ protected int file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, - int mode, int text) + size_t level, int mode, int text) { struct mlist *ml; int rv, printed_something = 0, need_separator = 0; for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode, - text, 0, 0, &printed_something, &need_separator, + text, 0, level, &printed_something, &need_separator, NULL)) != 0) return rv; @@ -1680,6 +1680,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, break; case FILE_INDIRECT: + if (offset == 0) + return 0; if (nbytes < offset) return 0; sbuf = ms->o.buf; @@ -1687,7 +1689,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, ms->o.buf = NULL; ms->offset = 0; rv = file_softmagic(ms, s + offset, nbytes - offset, - BINTEST, text); + recursion_level, BINTEST, text); if ((ms->flags & MAGIC_DEBUG) != 0) fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); rbuf = ms->o.buf; diff --git b/ext/fileinfo/php_fileinfo.h a/ext/fileinfo/php_fileinfo.h index d8dec12..354ec7b 100644 --- b/ext/fileinfo/php_fileinfo.h +++ a/ext/fileinfo/php_fileinfo.h @@ -24,7 +24,7 @@ extern zend_module_entry fileinfo_module_entry; #define phpext_fileinfo_ptr &fileinfo_module_entry -#define PHP_FILEINFO_VERSION "1.0.5-dev" +#define PHP_FILEINFO_VERSION "1.0.5" #ifdef PHP_WIN32 #define PHP_FILEINFO_API __declspec(dllexport) diff --git b/ext/fileinfo/tests/cve-2014-1943.phpt a/ext/fileinfo/tests/cve-2014-1943.phpt new file mode 100644 index 0000000..b2e9c17 --- /dev/null +++ a/ext/fileinfo/tests/cve-2014-1943.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #66731: file: infinite recursion +--SKIPIF-- +<?php +if (!class_exists('finfo')) + die('skip no fileinfo extension'); +--FILE-- +<?php +$fd = __DIR__.'/cve-2014-1943.data'; +$fm = __DIR__.'/cve-2014-1943.magic'; + +$a = "\105\122\000\000\000\000\000"; +$b = str_repeat("\001", 250000); +$m = "0 byte x\n". + ">(1.b) indirect x\n"; + +file_put_contents($fd, $a); +$fi = finfo_open(FILEINFO_NONE); +var_dump(finfo_file($fi, $fd)); +finfo_close($fi); + +file_put_contents($fd, $b); +file_put_contents($fm, $m); +$fi = finfo_open(FILEINFO_NONE, $fm); +var_dump(finfo_file($fi, $fd)); +finfo_close($fi); +?> +Done +--CLEAN-- +<?php +@unlink(__DIR__.'/cve-2014-1943.data'); +@unlink(__DIR__.'/cve-2014-1943.magic'); +?> +--EXPECTF-- +string(%d) "%s" + +Warning: finfo_file(): Failed identify data 0:(null) in %s on line %d +bool(false) +Done diff --git b/ext/json/json.c a/ext/json/json.c index 4ab6278..b0191c3 100644 --- b/ext/json/json.c +++ a/ext/json/json.c @@ -39,7 +39,7 @@ static PHP_FUNCTION(json_last_error_msg); static const char digits[] = "0123456789abcdef"; -zend_class_entry *php_json_serializable_ce; +PHP_JSON_API zend_class_entry *php_json_serializable_ce; ZEND_DECLARE_MODULE_GLOBALS(json) diff --git b/ext/json/php_json.h a/ext/json/php_json.h index 637c5ea..e00de6a 100644 --- b/ext/json/php_json.h +++ a/ext/json/php_json.h @@ -51,7 +51,7 @@ ZEND_END_MODULE_GLOBALS(json) PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC); PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, int options, long depth TSRMLS_DC); -extern zend_class_entry *php_json_serializable_ce; +extern PHP_JSON_API zend_class_entry *php_json_serializable_ce; /* json_encode() options */ diff --git b/ext/openssl/openssl.c a/ext/openssl/openssl.c old mode 100644 new mode 100755 index 3d73751..f1e582b --- b/ext/openssl/openssl.c +++ a/ext/openssl/openssl.c @@ -3026,7 +3026,7 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC) } break; #endif -#ifdef EVP_PKEY_EC +#if OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_EC) && defined(EVP_PKEY_EC) case EVP_PKEY_EC: assert(pkey->pkey.ec != NULL); @@ -3435,7 +3435,7 @@ PHP_FUNCTION(openssl_pkey_get_details) } break; -#ifdef EVP_PKEY_EC +#ifdef EVP_PKEY_EC case EVP_PKEY_EC: ktype = OPENSSL_KEYTYPE_EC; break; diff --git b/ext/pgsql/pgsql.c a/ext/pgsql/pgsql.c index b37f40a..be915ae 100644 --- b/ext/pgsql/pgsql.c +++ a/ext/pgsql/pgsql.c @@ -15,8 +15,8 @@ | Authors: Zeev Suraski <zeev@zend.com> | | Jouni Ahto <jouni.ahto@exdec.fi> | | Yasuo Ohgaki <yohgaki@php.net> | - | Youichi Iwakiri <yiwakiri@st.rim.or.jp> (pg_copy_*) | - | Chris Kings-Lynne <chriskl@php.net> (v3 protocol) | + | Youichi Iwakiri <yiwakiri@st.rim.or.jp> (pg_copy_*) | + | Chris Kings-Lynne <chriskl@php.net> (v3 protocol) | +----------------------------------------------------------------------+ */ @@ -746,6 +746,105 @@ ZEND_GET_MODULE(pgsql) static int le_link, le_plink, le_result, le_lofp, le_string; +/* Compatibility definitions */ + +#ifndef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT +#define pg_encoding_to_char(x) "SQL_ASCII" +#endif + +#if !HAVE_PQESCAPE_CONN +#define PQescapeStringConn(conn, to, form, len, error) PQescapeString(to, from, len) +#endif + +#if HAVE_PQESCAPELITERAL +#define PGSQLescapeLiteral(conn, str, len) PQescapeLiteral(conn, str, len) +#define PGSQLescapeIdentifier(conn, str, len) PQescapeIdentifier(conn, str, len) +#define PGSQLfree(a) PQfreemem(a) +#else +#define PGSQLescapeLiteral(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 0) +#define PGSQLescapeLiteral2(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 1) +#define PGSQLescapeIdentifier(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 0, 0) +#define PGSQLfree(a) efree(a) + +/* emulate libpq's PQescapeInternal() 9.0 or later */ +static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal, int safe) { + char *result, *rp, *s; + size_t tmp_len; + + if (!conn) { + return NULL; + } + + /* allocate enough memory */ + rp = result = (char *)safe_emalloc(len, 2, 5); /* leading " E" needs extra 2 bytes + quote_chars on both end for 2 bytes + NULL */ + + if (escape_literal) { + size_t new_len; + + if (safe) { + char *tmp = (char *)safe_emalloc(len, 2, 1); + *rp++ = '\''; + /* PQescapeString does not escape \, but it handles multibyte chars safely. + This escape is incompatible with PQescapeLiteral. */ + new_len = PQescapeStringConn(conn, tmp, str, len, NULL); + strncpy(rp, tmp, new_len); + efree(tmp); + rp += new_len; + } else { + char *encoding; + /* This is compatible with PQescapeLiteral, but it cannot handle multbyte chars + such as SJIS, BIG5. Raise warning and return NULL by checking + client_encoding. */ + encoding = (char *) pg_encoding_to_char(PQclientEncoding(conn)); + if (!strncmp(encoding, "SJIS", sizeof("SJIS")-1) || + !strncmp(encoding, "SHIFT_JIS_2004", sizeof("SHIFT_JIS_2004")-1) || + !strncmp(encoding, "BIG5", sizeof("BIG5")-1) || + !strncmp(encoding, "GB18030", sizeof("GB18030")-1) || + !strncmp(encoding, "GBK", sizeof("GBK")-1) || + !strncmp(encoding, "JOHAB", sizeof("JOHAB")-1) || + !strncmp(encoding, "UHC", sizeof("UHC")-1) ) { + TSRMLS_FETCH(); + + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsafe encoding is used. Do not use '%s' encoding or use PostgreSQL 9.0 or later libpq.", encoding); + } + /* check backslashes */ + tmp_len = strspn(str, "\\"); + if (tmp_len != len) { + /* add " E" for escaping slashes */ + *rp++ = ' '; + *rp++ = 'E'; + } + *rp++ = '\''; + for (s = (char *)str; s - str < len; ++s) { + if (*s == '\'' || *s == '\\') { + *rp++ = *s; + *rp++ = *s; + } else { + *rp++ = *s; + } + } + } + *rp++ = '\''; + } else { + /* Identifier escape. */ + *rp++ = '"'; + for (s = (char *)str; s - str < len; ++s) { + if (*s == '"') { + *rp++ = '"'; + *rp++ = '"'; + } else { + *rp++ = *s; + } + } + *rp++ = '"'; + } + *rp = '\0'; + + return result; +} +#endif + + /* {{{ _php_pgsql_trim_message */ static char * _php_pgsql_trim_message(const char *message, int *len) { @@ -774,16 +873,16 @@ static inline char * _php_pgsql_trim_result(PGconn * pgsql, char **buf) #define PQErrorMessageTrim(pgsql, buf) _php_pgsql_trim_result(pgsql, buf) -#define PHP_PQ_ERROR(text, pgsql) { \ - char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, text, msgbuf); \ - efree(msgbuf); \ +#define PHP_PQ_ERROR(text, pgsql) { \ + char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, text, msgbuf); \ + efree(msgbuf); \ } \ /* {{{ php_pgsql_set_default_link */ static void php_pgsql_set_default_link(int id TSRMLS_DC) -{ +{ zend_list_addref(id); if (PGG(default_link) != -1) { @@ -851,10 +950,10 @@ static void _php_pgsql_notice_ptr_dtor(void **ptr) { php_pgsql_notice *notice = (php_pgsql_notice *)*ptr; if (notice) { - efree(notice->message); - efree(notice); - notice = NULL; - } + efree(notice->message); + efree(notice); + notice = NULL; + } } /* }}} */ @@ -944,57 +1043,7 @@ static int _php_pgsql_detect_identifier_escape(const char *identifier, size_t le return SUCCESS; } -#if !HAVE_PQESCAPELITERAL -/* {{{ _php_pgsql_escape_identifier - * Since PQescapeIdentifier() is unavailable (PostgreSQL 9.0 <), idenfifers - * should be escaped by pgsql module. - * Note: this function does not care for encoding. Therefore users should not - * use this with SJIS/BIG5 etc. (i.e. Encoding base injection may possible with - * before PostgreSQL 9.0) - */ -static char *_php_pgsql_escape_identifier(const char *field, size_t field_len) -{ - ulong field_escaped_len = field_len*2 + 3; - ulong i, j = 0; - char *field_escaped; - - field_escaped = (char *)malloc(field_escaped_len); - field_escaped[j++] = '"'; - for (i = 0; i < field_len; i++) { - if (field[i] == '"') { - field_escaped[j++] = '"'; - field_escaped[j++] = '"'; - } else { - field_escaped[j++] = field[i]; - } - } - field_escaped[j++] = '"'; - field_escaped[j] = '\0'; - return field_escaped; -} -/* }}} */ -#endif - -/* {{{ _php_pgsql_strndup, no strndup should be used */ -static char *_php_pgsql_strndup(const char *s, size_t len) -{ - char *new; - if (NULL == s) { - return (char *)NULL; - } - - new = (char *) malloc(len + 1); - - if (NULL == new) { - return (char *)NULL; - } - - new[len] = '\0'; - - return memmove(new, s, len); -} -/* }}} */ /* {{{ PHP_INI */ @@ -1023,7 +1072,7 @@ static PHP_GINIT_FUNCTION(pgsql) PHP_MINIT_FUNCTION(pgsql) { REGISTER_INI_ENTRIES(); - + le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number); le_plink = zend_register_list_destructors_ex(NULL, _close_pgsql_plink, "pgsql link persistent", module_number); le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number); @@ -1159,7 +1208,7 @@ PHP_MINFO_FUNCTION(pgsql) #else php_info_print_table_row(2, "SSL support", "disabled"); #endif -#endif /* HAVE_PG_CONFIG_H */ +#endif /* HAVE_PG_CONFIG_H */ snprintf(buf, sizeof(buf), "%ld", PGG(num_persistent)); php_info_print_table_row(2, "Active Persistent Links", buf); snprintf(buf, sizeof(buf), "%ld", PGG(num_links)); @@ -1227,7 +1276,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) break; } } - + if (persistent && PGG(allow_persistent)) { zend_rsrc_list_entry *le; @@ -1310,7 +1359,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) ZEND_REGISTER_RESOURCE(return_value, pgsql, le_plink); } else { /* Non persistent connection */ zend_rsrc_list_entry *index_ptr,new_index_ptr; - + /* first we check the hash for the hashed_details key. if it exists, * it should point us to the right offset where the actual pgsql link sits. * if it doesn't, open a new pgsql link, add it to the resource list, @@ -1374,7 +1423,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) cleanup: smart_str_free(&str); return; - + err: smart_str_free(&str); RETURN_FALSE; @@ -1418,11 +1467,11 @@ PHP_FUNCTION(pg_close) zval *pgsql_link = NULL; int id = -1, argc = ZEND_NUM_ARGS(); PGconn *pgsql; - + if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { return; } - + if (argc == 0) { id = PGG(default_link); CHECK_DEFAULT_LINK(id); @@ -1430,7 +1479,7 @@ PHP_FUNCTION(pg_close) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1438,7 +1487,7 @@ PHP_FUNCTION(pg_close) zend_list_delete(Z_RESVAL_P(pgsql_link)); } - if (id!=-1 + if (id!=-1 || (pgsql_link && Z_RESVAL_P(pgsql_link)==PGG(default_link))) { zend_list_delete(PGG(default_link)); PGG(default_link) = -1; @@ -1457,6 +1506,7 @@ PHP_FUNCTION(pg_close) #define PHP_PG_HOST 6 #define PHP_PG_VERSION 7 + /* {{{ php_pgsql_get_link_info */ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) @@ -1477,7 +1527,7 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1603,7 +1653,7 @@ PHP_FUNCTION(pg_parameter_status) } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1634,7 +1684,7 @@ PHP_FUNCTION(pg_ping) } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1709,7 +1759,7 @@ PHP_FUNCTION(pg_query) } else { status = (ExecStatusType) PQstatus(pgsql); } - + switch (status) { case PGRES_EMPTY_QUERY: case PGRES_BAD_RESPONSE: @@ -1805,7 +1855,7 @@ PHP_FUNCTION(pg_query_params) if (num_params > 0) { int i = 0; params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - + for(i = 0; i < num_params; i++) { if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); @@ -1902,10 +1952,10 @@ PHP_FUNCTION(pg_prepare) return; } } - + if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1932,7 +1982,7 @@ PHP_FUNCTION(pg_prepare) } else { status = (ExecStatusType) PQstatus(pgsql); } - + switch (status) { case PGRES_EMPTY_QUERY: case PGRES_BAD_RESPONSE: @@ -2012,7 +2062,7 @@ PHP_FUNCTION(pg_execute) if (num_params > 0) { int i = 0; params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - + for(i = 0; i < num_params; i++) { if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); @@ -2054,7 +2104,7 @@ PHP_FUNCTION(pg_execute) } else { status = (ExecStatusType) PQstatus(pgsql); } - + _php_pgsql_free_params(params, num_params); switch (status) { @@ -2206,7 +2256,7 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) num_rows = PQntuples(result); oid_offset = PQfnumber(result,"oid"); name_offset = PQfnumber(result,"typname"); - + for (i=0; i<num_rows; i++) { if ((tmp_oid = PQgetvalue(result,i,oid_offset))==NULL) { continue; @@ -2216,7 +2266,7 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) smart_str_appends(&str, "pgsql_oid_"); smart_str_appends(&str, tmp_oid); smart_str_0(&str); - + if ((tmp_name = PQgetvalue(result,i,name_offset))==NULL) { continue; } @@ -2233,7 +2283,7 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) smart_str_free(&str); return ret; } -/* }}} */ +/* }}} */ #ifdef HAVE_PQFTABLE /* {{{ proto mixed pg_field_table(resource result, int field_number[, bool oid_only]) @@ -2266,7 +2316,6 @@ PHP_FUNCTION(pg_field_table) RETURN_FALSE; } - if (return_oid) { #if UINT_MAX > LONG_MAX /* Oid is unsigned int, we don't need this code, where LONG is wider */ if (oid > LONG_MAX) { @@ -2296,7 +2345,6 @@ PHP_FUNCTION(pg_field_table) smart_str_append_unsigned(&querystr, oid); smart_str_0(&querystr); - if ((tmp_res = PQexec(pg_result->conn, querystr.c)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) { if (tmp_res) { PQclear(tmp_res); @@ -2324,8 +2372,8 @@ PHP_FUNCTION(pg_field_table) } } -/* }}} */ -#endif +/* }}} */ +#endif #define PHP_PG_FIELD_NAME 1 #define PHP_PG_FIELD_SIZE 2 @@ -2341,11 +2389,11 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ PGresult *pgsql_result; pgsql_result_handle *pg_result; Oid oid; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) { return; } - + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; @@ -2354,7 +2402,7 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified"); RETURN_FALSE; } - + switch (entry_type) { case PHP_PG_FIELD_NAME: Z_STRVAL_P(return_value) = PQfname(pgsql_result, field); @@ -2441,11 +2489,11 @@ PHP_FUNCTION(pg_field_num) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &result, &field, &field_len) == FAILURE) { return; } - + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; - + Z_LVAL_P(return_value) = PQfnumber(pgsql_result, field); Z_TYPE_P(return_value) = IS_LONG; } @@ -2460,7 +2508,7 @@ PHP_FUNCTION(pg_fetch_result) PGresult *pgsql_result; pgsql_result_handle *pg_result; int field_offset, pgsql_row, argc = ZEND_NUM_ARGS(); - + if (argc == 2) { if (zend_parse_parameters(argc TSRMLS_CC, "rZ", &result, &field) == FAILURE) { return; @@ -2503,7 +2551,7 @@ PHP_FUNCTION(pg_fetch_result) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified"); RETURN_FALSE; } - + if (PQgetisnull(pgsql_result, pgsql_row, field_offset)) { Z_TYPE_P(return_value) = IS_NULL; } else { @@ -2606,12 +2654,12 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, data = safe_estrndup(element, element_len); data_len = element_len; - + if (result_type & PGSQL_NUM) { add_index_stringl(return_value, i, data, data_len, should_copy); should_copy=1; } - + if (result_type & PGSQL_ASSOC) { field_name = PQfname(pgsql_result, i); add_assoc_stringl(return_value, field_name, data, data_len, should_copy); @@ -2624,11 +2672,11 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, zval dataset = *return_value; zend_fcall_info fci; zend_fcall_info_cache fcc; - zval *retval_ptr; - + zval *retval_ptr; + object_and_properties_init(return_value, ce, NULL); zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC); - + if (ce->constructor) { fci.size = sizeof(fci); fci.function_table = &ce->function_table; @@ -2640,7 +2688,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, if (Z_TYPE_P(ctor_params) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(ctor_params); Bucket *p; - + fci.param_count = 0; fci.params = safe_emalloc(sizeof(zval***), ht->nNumOfElements, 0); p = ht->pListHead; @@ -2669,7 +2717,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(return_value); fcc.object_ptr = return_value; - + if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); } else { @@ -2775,7 +2823,7 @@ PHP_FUNCTION(pg_fetch_all_columns) array_init(return_value); - if ((pg_numrows = PQntuples(pgsql_result)) <= 0) { + if ((pg_numrows = PQntuples(pgsql_result)) <= 0) { return; } @@ -2784,7 +2832,7 @@ PHP_FUNCTION(pg_fetch_all_columns) add_next_index_null(return_value); } else { add_next_index_string(return_value, PQgetvalue(pgsql_result, pg_row, colno), 1); - } + } } } /* }}} */ @@ -2806,7 +2854,7 @@ PHP_FUNCTION(pg_result_seek) if (row < 0 || row >= PQntuples(pg_result->result)) { RETURN_FALSE; } - + /* seek to offset */ pg_result->row = row; RETURN_TRUE; @@ -2836,7 +2884,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) return; } } - + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; @@ -2856,7 +2904,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) RETURN_FALSE; } } - + switch(Z_TYPE_PP(field)) { case IS_STRING: convert_to_string_ex(field); @@ -2871,7 +2919,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified"); RETURN_FALSE; } - + switch (entry_type) { case PHP_PG_DATA_LENGTH: Z_LVAL_P(return_value) = PQgetlength(pgsql_result, pgsql_row, field_offset); @@ -2906,7 +2954,7 @@ PHP_FUNCTION(pg_free_result) { zval *result; pgsql_result_handle *pg_result; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { return; } @@ -2934,7 +2982,7 @@ PHP_FUNCTION(pg_last_oid) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { return; } - + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; #ifdef HAVE_PQOIDVALUE @@ -2965,18 +3013,18 @@ PHP_FUNCTION(pg_trace) FILE *fp = NULL; php_stream *stream; id = PGG(default_link); - + if (zend_parse_parameters(argc TSRMLS_CC, "s|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) { return; } if (argc < 3) { CHECK_DEFAULT_LINK(id); - } + } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3015,7 +3063,7 @@ PHP_FUNCTION(pg_untrace) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); PQuntrace(pgsql); @@ -3027,10 +3075,10 @@ PHP_FUNCTION(pg_untrace) Create a large object */ PHP_FUNCTION(pg_lo_create) { - zval *pgsql_link = NULL, *oid = NULL; - PGconn *pgsql; - Oid pgsql_oid, wanted_oid = InvalidOid; - int id = -1, argc = ZEND_NUM_ARGS(); + zval *pgsql_link = NULL, *oid = NULL; + PGconn *pgsql; + Oid pgsql_oid, wanted_oid = InvalidOid; + int id = -1, argc = ZEND_NUM_ARGS(); if (zend_parse_parameters(argc TSRMLS_CC, "|zz", &pgsql_link, &oid) == FAILURE) { return; @@ -3052,12 +3100,12 @@ PHP_FUNCTION(pg_lo_create) ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); if (oid) { -#ifndef HAVE_PG_LO_CREATE - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "OID value passing not supported"); +#ifndef HAVE_PG_LO_CREATE + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Passing OID value is not supported. Upgrade your PostgreSQL"); #else switch (Z_TYPE_P(oid)) { case IS_STRING: - { + { char *end_ptr; wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10); if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) { @@ -3083,7 +3131,7 @@ PHP_FUNCTION(pg_lo_create) RETURN_FALSE; } - PGSQL_RETURN_OID(pgsql_oid); + PGSQL_RETURN_OID(pgsql_oid); #endif } @@ -3092,7 +3140,7 @@ PHP_FUNCTION(pg_lo_create) RETURN_FALSE; } - PGSQL_RETURN_OID(pgsql_oid); + PGSQL_RETURN_OID(pgsql_oid); } /* }}} */ @@ -3154,7 +3202,7 @@ PHP_FUNCTION(pg_lo_unlink) } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3226,7 +3274,7 @@ PHP_FUNCTION(pg_lo_open) } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3318,8 +3366,8 @@ PHP_FUNCTION(pg_lo_close) Read a large object */ PHP_FUNCTION(pg_lo_read) { - zval *pgsql_id; - long len; + zval *pgsql_id; + long len; int buf_len = PGSQL_LO_READ_BUF_SIZE, nbytes, argc = ZEND_NUM_ARGS(); char *buf; pgLofp *pgsql; @@ -3446,7 +3494,7 @@ PHP_FUNCTION(pg_lo_import) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3457,7 +3505,7 @@ PHP_FUNCTION(pg_lo_import) Oid wanted_oid; switch (Z_TYPE_P(oid)) { case IS_STRING: - { + { char *end_ptr; wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10); if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) { @@ -3579,13 +3627,13 @@ PHP_FUNCTION(pg_lo_export) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); if (lo_export(pgsql, oid, file_out)) { RETURN_TRUE; - } + } RETURN_FALSE; } /* }}} */ @@ -3700,7 +3748,7 @@ PHP_FUNCTION(pg_set_client_encoding) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3734,10 +3782,6 @@ PHP_FUNCTION(pg_client_encoding) /* Just do the same as found in PostgreSQL sources... */ -#ifndef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT -#define pg_encoding_to_char(x) "SQL_ASCII" -#endif - Z_STRVAL_P(return_value) = (char *) pg_encoding_to_char(PQclientEncoding(pgsql)); Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); Z_STRVAL_P(return_value) = (char *) estrdup(Z_STRVAL_P(return_value)); @@ -3770,7 +3814,7 @@ PHP_FUNCTION(pg_end_copy) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3906,7 +3950,7 @@ PHP_FUNCTION(pg_copy_to) PHP_PQ_ERROR("getline failed: %s", pgsql); RETURN_FALSE; } - + if (copybuf[0] == '\\' && copybuf[1] == '.' && copybuf[2] == '\0') @@ -4114,12 +4158,11 @@ PHP_FUNCTION(pg_escape_string) } to = (char *) safe_emalloc(from_len, 2, 1); - #ifdef HAVE_PQESCAPE_CONN if (pgsql_link != NULL || id != -1) { ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); to_len = (int) PQescapeStringConn(pgsql, to, from, (size_t)from_len, NULL); - } else + } else #endif to_len = (int) PQescapeString(to, from, (size_t)from_len); @@ -4194,7 +4237,7 @@ PHP_FUNCTION(pg_escape_bytea) */ static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen) { - size_t buflen; + size_t buflen; unsigned char *buffer, *sp, *bp; @@ -4254,7 +4297,7 @@ static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t * memcpy(buf, sp-2, 3); buf[3] = '\0'; start = buf; - *bp = (unsigned char)strtoul(start, (char **)&end, 8); + *bp = (unsigned char)strtoul(start, (char **)&end, 8); buflen -= 3; state = 0; } @@ -4303,61 +4346,13 @@ PHP_FUNCTION(pg_unescape_bytea) #endif #ifdef HAVE_PQESCAPE -#if !HAVE_PQESCAPELITERAL -/* emulate libpq's PQescapeInternal() 9.0 or later */ -static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal) { - char *result, *rp; - const char *s; - size_t tmp_len; - int input_len = len; - char quote_char = escape_literal ? '\'' : '"'; - - if (!conn) { - return NULL; - } - - /* - * NOTE: multibyte strings that could cointain slashes should be considered. - * (e.g. SJIS, BIG5) However, it cannot be done without valid PGconn and mbstring. - * Therefore, this function does not support such encodings currently. - * FIXME: add encoding check and skip multibyte char bytes if there is vaild PGconn. - */ - - /* allocate enough memory */ - rp = result = (char *)emalloc(len*2 + 5); /* leading " E" needs extra 2 bytes + quote_chars on both end for 2 bytes + NULL */ - - if (escape_literal) { - /* check backslashes */ - tmp_len = strspn(str, "\\"); - if (tmp_len != len) { - /* add " E" for escaping slashes */ - *rp++ = ' '; - *rp++ = 'E'; - } - } - /* open quote */ - *rp++ = quote_char; - for (s = str; s - str < input_len; ++s) { - if (*s == quote_char || (escape_literal && *s == '\\')) { - *rp++ = *s; - *rp++ = *s; - } else { - *rp++ = *s; - } - } - *rp++ = quote_char; - *rp = '\0'; - - return result; -} -#endif - static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_literal) { char *from = NULL, *to = NULL; zval *pgsql_link = NULL; PGconn *pgsql; int from_len; int id = -1; + char *tmp; switch (ZEND_NUM_ARGS()) { case 1: @@ -4385,30 +4380,18 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot get pgsql link"); RETURN_FALSE; } -#ifdef HAVE_PQESCAPELITERAL - /* Use a block with a local var to avoid unused variable warnings */ - { - char *tmp; - if (escape_literal) { - tmp = PQescapeLiteral(pgsql, from, (size_t)from_len); - } else { - tmp = PQescapeIdentifier(pgsql, from, (size_t)from_len); - } - if (!tmp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Failed to escape"); - RETURN_FALSE; - } - to = estrdup(tmp); - PQfreemem(tmp); + if (escape_literal) { + tmp = PGSQLescapeLiteral(pgsql, from, (size_t)from_len); + } else { + tmp = PGSQLescapeIdentifier(pgsql, from, (size_t)from_len); } -#else - to = php_pgsql_PQescapeInternal(pgsql, from, (size_t)from_len, escape_literal); - if (!to) { + if (!tmp) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Failed to escape"); RETURN_FALSE; } -#endif + to = estrdup(tmp); + PGSQLfree(tmp); RETURN_STRING(to, 0); } @@ -4456,6 +4439,7 @@ PHP_FUNCTION(pg_result_error) } /* }}} */ + #if HAVE_PQRESULTERRORFIELD /* {{{ proto string pg_result_error_field(resource result, int fieldcode) Get error message field associated with result */ @@ -4501,6 +4485,7 @@ PHP_FUNCTION(pg_result_error_field) /* }}} */ #endif + /* {{{ proto int pg_connection_status(resource connection) Get connection status */ PHP_FUNCTION(pg_connection_status) @@ -4521,6 +4506,7 @@ PHP_FUNCTION(pg_connection_status) /* }}} */ + #if HAVE_PGTRANSACTIONSTATUS /* {{{ proto int pg_transaction_status(resource connection) Get transaction status */ @@ -4543,6 +4529,7 @@ PHP_FUNCTION(pg_transaction_status) /* }}} */ + /* {{{ proto bool pg_connection_reset(resource connection) Reset connection (reconnect) */ PHP_FUNCTION(pg_connection_reset) @@ -4564,12 +4551,13 @@ PHP_FUNCTION(pg_connection_reset) } RETURN_TRUE; } - /* }}} */ + #define PHP_PG_ASYNC_IS_BUSY 1 #define PHP_PG_ASYNC_REQUEST_CANCEL 2 - + + /* {{{ php_pgsql_flush_query */ static int php_pgsql_flush_query(PGconn *pgsql TSRMLS_DC) @@ -4589,7 +4577,8 @@ static int php_pgsql_flush_query(PGconn *pgsql TSRMLS_DC) return leftover; } /* }}} */ - + + /* {{{ php_pgsql_do_async */ static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) @@ -4819,7 +4808,7 @@ PHP_FUNCTION(pg_send_prepare) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -5107,7 +5096,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z size_t new_len; int i, num_rows; zval *elem; - + if (!*table_name) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The table name must be specified"); return FAILURE; @@ -5127,25 +5116,17 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z "FROM pg_class as c, pg_attribute a, pg_type t, pg_namespace n " "WHERE a.attnum > 0 AND a.attrelid = c.oid AND c.relname = '"); escaped = (char *)safe_emalloc(strlen(tmp_name2), 2, 1); -#if HAVE_PQESCAPE_CONN new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, strlen(tmp_name2), NULL); -#else - new_len = PQescapeString(escaped, tmp_name2, strlen(tmp_name2)); -#endif if (new_len) { - smart_str_appends(&querystr, escaped); + smart_str_appendl(&querystr, escaped, new_len); } efree(escaped); smart_str_appends(&querystr, "' AND c.relnamespace = n.oid AND n.nspname = '"); escaped = (char *)safe_emalloc(strlen(tmp_name), 2, 1); -#if HAVE_PQESCAPE_CONN new_len = PQescapeStringConn(pg_link, escaped, tmp_name, strlen(tmp_name), NULL); -#else - new_len = PQescapeString(escaped, tmp_name, strlen(tmp_name)); -#endif if (new_len) { - smart_str_appends(&querystr, escaped); + smart_str_appendl(&querystr, escaped, new_len); } efree(escaped); @@ -5208,7 +5189,7 @@ PHP_FUNCTION(pg_meta_data) uint table_name_len; PGconn *pgsql; int id = -1; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &table_name, &table_name_len) == FAILURE) { return; @@ -5235,13 +5216,14 @@ PHP_FUNCTION(pg_meta_data) } /* }}} */ + /* {{{ php_pgsql_get_data_type */ static php_pgsql_data_type php_pgsql_get_data_type(const char *type_name, size_t len) { - /* This is stupid way to do. I'll fix it when I decied how to support + /* This is stupid way to do. I'll fix it when I decied how to support user defined types. (Yasuo) */ - + /* boolean */ if (!strcmp(type_name, "bool")|| !strcmp(type_name, "boolean")) return PG_BOOL; @@ -5320,25 +5302,35 @@ static php_pgsql_data_type php_pgsql_get_data_type(const char *type_name, size_t return PG_POLYGON; if (!strcmp(type_name, "circle")) return PG_CIRCLE; - + return PG_UNKNOWN; } /* }}} */ /* {{{ php_pgsql_convert_match - * test field value with regular expression specified. + * test field value with regular expression specified. */ -static int php_pgsql_convert_match(const char *str, const char *regex , int icase TSRMLS_DC) +static int php_pgsql_convert_match(const char *str, size_t str_len, const char *regex , int icase TSRMLS_DC) { - regex_t re; + regex_t re; regmatch_t *subs; int regopt = REG_EXTENDED; int regerr, ret = SUCCESS; + int i; + + /* Check invalid chars for POSIX regex */ + for (i = 0; i < str_len; i++) { + if (str[i] == '\n' || + str[i] == '\r' || + str[i] == '\0' ) { + return FAILURE; + } + } if (icase) { regopt |= REG_ICASE; } - + regerr = regcomp(&re, regex, regopt); if (regerr) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot compile regex"); @@ -5349,7 +5341,7 @@ static int php_pgsql_convert_match(const char *str, const char *regex , int icas regerr = regexec(&re, str, re.re_nsub+1, subs, 0); if (regerr == REG_NOMATCH) { -#ifdef PHP_DEBUG +#ifdef PHP_DEBUG php_error_docref(NULL TSRMLS_CC, E_NOTICE, "'%s' does not match with '%s'", str, regex); #endif ret = FAILURE; @@ -5371,7 +5363,7 @@ static int php_pgsql_convert_match(const char *str, const char *regex , int icas static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) { smart_str str = {0}; - + assert(Z_TYPE_P(src) == IS_STRING); assert(should_free == 1 || should_free == 0); @@ -5380,7 +5372,7 @@ static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) smart_str_appendl(&str, Z_STRVAL_P(src), Z_STRLEN_P(src)); smart_str_appendc(&str, '\''); smart_str_0(&str); - + if (should_free) { efree(Z_STRVAL_P(src)); } @@ -5404,7 +5396,7 @@ static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected NULL for 'NOT NULL' field '%s'", field ); \ err = 1; \ } \ - } + } /* {{{ php_pgsql_convert * check and convert array values (fieldname=>vlaue pair) for sql @@ -5418,7 +5410,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con zval *meta, **def, **type, **not_null, **has_default, **is_enum, **val, *new_val; int key_type, err = 0, skip_field; php_pgsql_data_type data_type; - + assert(pg_link != NULL); assert(Z_TYPE_P(values) == IS_ARRAY); assert(Z_TYPE_P(result) == IS_ARRAY); @@ -5441,7 +5433,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos)) { skip_field = 0; new_val = NULL; - + if ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &field, &field_len, &num_idx, 0, &pos)) == HASH_KEY_NON_EXISTENT) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to get array key type"); err = 1; @@ -5522,7 +5514,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_LONG: case IS_BOOL: if (Z_LVAL_PP(val)) { @@ -5545,7 +5537,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects string, null, long or boolelan value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_OID: case PG_INT2: case PG_INT4: @@ -5557,7 +5549,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([+-]{0,1}[0-9]+)$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([+-]{0,1}[0-9]+)$", 0 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5565,7 +5557,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); convert_to_long_ex(&new_val); @@ -5599,7 +5591,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([+-]{0,1}[0-9]+)|([+-]{0,1}[0-9]*[\\.][0-9]+)|([+-]{0,1}[0-9]+[\\.][0-9]*)$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([+-]{0,1}[0-9]+)|([+-]{0,1}[0-9]*[\\.][0-9]+)|([+-]{0,1}[0-9]+[\\.][0-9]*)$", 0 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5607,15 +5599,15 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_LONG: ZVAL_LONG(new_val, Z_LVAL_PP(val)); break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5642,26 +5634,20 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } else { + char *tmp; Z_TYPE_P(new_val) = IS_STRING; -#if HAVE_PQESCAPE_CONN - { - char *tmp; - tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1); - Z_STRLEN_P(new_val) = (int)PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL); - Z_STRVAL_P(new_val) = tmp; - } -#else - Z_STRVAL_P(new_val) = (int)PQescapeString(Z_STRVAL_PP(val), Z_STRLEN_PP(val), &Z_STRLEN_P(new_val), 0 TSRMLS_CC); -#endif + tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1); + Z_STRLEN_P(new_val) = (int)PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL); + Z_STRVAL_P(new_val) = tmp; php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); } break; - + case IS_LONG: ZVAL_LONG(new_val, Z_LVAL_PP(val)); convert_to_string_ex(&new_val); break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); convert_to_string_ex(&new_val); @@ -5679,7 +5665,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_UNIX_TIME: case PG_UNIX_TIME_INTERVAL: /* these are the actallay a integer */ @@ -5690,25 +5676,25 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: Better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^[0-9]+$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^[0-9]+$", 0 TSRMLS_CC) == FAILURE) { err = 1; - } + } else { ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); convert_to_long_ex(&new_val); } } break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); convert_to_long_ex(&new_val); break; - + case IS_LONG: ZVAL_LONG(new_val, Z_LVAL_PP(val)); break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5721,7 +5707,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for '%s' (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_CIDR: case PG_INET: switch (Z_TYPE_PP(val)) { @@ -5731,7 +5717,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: Better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/[0-9]{1,2}){0,1}$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/[0-9]{1,2}){0,1}$", 0 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5747,13 +5733,13 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con default: err = 1; - } + } PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for '%s' (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_TIME_WITH_TIMEZONE: case PG_TIMESTAMP: case PG_TIMESTAMP_WITH_TIMEZONE: @@ -5765,7 +5751,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con ZVAL_STRINGL(new_val, "NOW()", sizeof("NOW()")-1, 1); } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}(\\.[0-9]+){0,1}([ \\t]*([+-][0-9]{1,4}(:[0-9]{1,2}){0,1}|[-a-zA-Z_/+]{1,50})){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}(\\.[0-9]+){0,1}([ \\t]*([+-][0-9]{1,4}(:[0-9]{1,2}){0,1}|[-a-zA-Z_/+]{1,50})){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { err = 1; } else { ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); @@ -5773,7 +5759,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_NULL: ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); break; @@ -5786,7 +5772,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_DATE: switch(Z_TYPE_PP(val)) { case IS_STRING: @@ -5795,7 +5781,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})$", 1 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5804,7 +5790,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5826,7 +5812,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5835,7 +5821,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5872,10 +5858,10 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con Quantities of days, hours, minutes, and seconds can be specified without explicit unit markings. For example, '1 12:59:10' is read the same as '1 day 12 hours 59 min 10 sec'. - */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), + */ + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^(@?[ \\t]+)?(" - + /* Textual time units and their abbreviations: */ "(([-+]?[ \\t]+)?" "[0-9]+(\\.[0-9]*)?[ \\t]*" @@ -5912,9 +5898,9 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); } - } + } break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5956,12 +5942,12 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con Z_STRLEN_P(new_val) = s.len; } break; - + case IS_LONG: ZVAL_LONG(new_val, Z_LVAL_PP(val)); convert_to_string_ex(&new_val); break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); convert_to_string_ex(&new_val); @@ -5988,7 +5974,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con ZVAL_STRING(new_val, "NULL", 1); } else { - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9a-f]{2,2}:){5,5}[0-9a-f]{2,2}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9a-f]{2,2}:){5,5}[0-9a-f]{2,2}$", 1 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5997,7 +5983,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -6032,7 +6018,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con err = 1; break; } /* switch */ - + if (err) { zval_dtor(new_val); FREE_ZVAL(new_val); @@ -6044,16 +6030,12 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con size_t field_len = strlen(field); if (_php_pgsql_detect_identifier_escape(field, field_len) == SUCCESS) { - escaped = _php_pgsql_strndup(field, field_len); + add_assoc_zval(result, field, new_val); } else { -#if HAVE_PQESCAPELITERAL - escaped = PQescapeIdentifier(pg_link, field, field_len); -#else - escaped = _php_pgsql_escape_identifier(field, field_len); -#endif + escaped = PGSQLescapeIdentifier(pg_link, field, field_len); + add_assoc_zval(result, escaped, new_val); + PGSQLfree(escaped); } - add_assoc_zval(result, escaped, new_val); - free(escaped); } } /* for */ zval_dtor(meta); @@ -6078,7 +6060,7 @@ PHP_FUNCTION(pg_convert) ulong option = 0; PGconn *pg_link; int id = -1; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|l", &pgsql_link, &table_name, &table_name_len, &values, &option) == FAILURE) { return; @@ -6138,31 +6120,24 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const c token = php_strtok_r(table_copy, ".", &tmp); len = strlen(token); if (_php_pgsql_detect_identifier_escape(token, len) == SUCCESS) { - escaped = _php_pgsql_strndup(token, len); + smart_str_appendl(querystr, token, len); } else { -#if HAVE_PQESCAPELITERAL - escaped = PQescapeIdentifier(pg_link, token, len); -#else - escaped = _php_pgsql_escape_identifier(token, len); -#endif + escaped = PGSQLescapeIdentifier(pg_link, token, len); + smart_str_appends(querystr, escaped); + PGSQLfree(escaped); } - smart_str_appends(querystr, escaped); - free(escaped); if (tmp && *tmp) { len = strlen(tmp); /* "schema"."table" format */ if (_php_pgsql_detect_identifier_escape(tmp, len) == SUCCESS) { - escaped = _php_pgsql_strndup(tmp, len); + smart_str_appendc(querystr, '.'); + smart_str_appendl(querystr, tmp, len); } else { -#if HAVE_PQESCAPELITERAL - escaped = PQescapeIdentifier(pg_link, tmp, len); -#else - escaped = _php_pgsql_escape_identifier(tmp, len); -#endif + escaped = PGSQLescapeIdentifier(pg_link, tmp, len); + smart_str_appendc(querystr, '.'); + smart_str_appends(querystr, escaped); + PGSQLfree(escaped); } - smart_str_appendc(querystr, '.'); - smart_str_appends(querystr, escaped); - free(escaped); } efree(table_copy); } @@ -6262,7 +6237,7 @@ no_values: cleanup: if (!(opt & PGSQL_DML_NO_CONV) && converted) { - zval_dtor(converted); + zval_dtor(converted); FREE_ZVAL(converted); } if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { @@ -6323,7 +6298,7 @@ static inline int build_assignment_string(smart_str *querystr, HashTable *ht, in for (zend_hash_internal_pointer_reset_ex(ht, &pos); zend_hash_get_current_data_ex(ht, (void **)&val, &pos) == SUCCESS; zend_hash_move_forward_ex(ht, &pos)) { - key_type = zend_hash_get_current_key_ex(ht, &fld, &fld_len, &num_idx, 0, &pos); + key_type = zend_hash_get_current_key_ex(ht, &fld, &fld_len, &num_idx, 0, &pos); if (key_type == HASH_KEY_IS_LONG) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects associative array for values to be inserted"); return -1; @@ -6334,7 +6309,7 @@ static inline int build_assignment_string(smart_str *querystr, HashTable *ht, in } else { smart_str_appendc(querystr, '='); } - + switch(Z_TYPE_PP(val)) { case IS_STRING: smart_str_appendl(querystr, Z_STRVAL_PP(val), Z_STRLEN_PP(val)); @@ -6463,7 +6438,7 @@ PHP_FUNCTION(pg_update) RETURN_STRING(sql, 0); } RETURN_TRUE; -} +} /* }}} */ /* {{{ php_pgsql_delete @@ -6510,7 +6485,7 @@ PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids cleanup: if (!(opt & PGSQL_DML_NO_CONV)) { - zval_dtor(ids_converted); + zval_dtor(ids_converted); FREE_ZVAL(ids_converted); } if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { @@ -6614,7 +6589,7 @@ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids assert(Z_TYPE_P(ids_array) == IS_ARRAY); assert(Z_TYPE_P(ret_array) == IS_ARRAY); assert(!(opt & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING))); - + if (zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) { return FAILURE; } @@ -6648,7 +6623,7 @@ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids cleanup: if (!(opt & PGSQL_DML_NO_CONV)) { - zval_dtor(ids_converted); + zval_dtor(ids_converted); FREE_ZVAL(ids_converted); } if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { @@ -6696,7 +6671,7 @@ PHP_FUNCTION(pg_select) RETURN_STRING(sql, 0); } return; -} +} /* }}} */ #endif diff --git b/ext/pgsql/php_pgsql.h a/ext/pgsql/php_pgsql.h index 12d6cfd..d0853d6 100644 --- b/ext/pgsql/php_pgsql.h +++ a/ext/pgsql/php_pgsql.h @@ -16,7 +16,7 @@ | Jouni Ahto <jouni.ahto@exdec.fi> | +----------------------------------------------------------------------+ */ - + /* $Id$ */ #ifndef PHP_PGSQL_H diff --git b/main/php_version.h a/main/php_version.h index 784ef62..34f5128 100644 --- b/main/php_version.h +++ a/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 5 #define PHP_MINOR_VERSION 5 -#define PHP_RELEASE_VERSION 9 +#define PHP_RELEASE_VERSION 11 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "5.5.9-dev" -#define PHP_VERSION_ID 50509 +#define PHP_VERSION "5.5.11-dev" +#define PHP_VERSION_ID 50511
diff --git b/NEWS a/NEWS index f1a02ee..32000e2 100644 --- b/NEWS +++ a/NEWS @@ -1,5 +1,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +?? ??? 2014, PHP 5.5.11 + ?? ??? 2014, PHP 5.5.10 - Core: @@ -9,6 +11,13 @@ PHP NEWS . Fixed bug #45528 (Allow the DateTimeZone constructor to accept timezones per offset too). (Derick) +- Fileinfo: + . Bug #66731 (file: infinite recursion) (CVE-2014-1943). (Remi) + +- JSON: + . Fixed bug #65753 (JsonSerializeable couldn't implement on module extension) + (chobieeee@php.net) + - LDAP: . Implemented ldap_modify_batch (https://wiki.php.net/rfc/ldap_modify_batch). (Ondřej Hošek) @@ -20,6 +29,11 @@ PHP NEWS - PCRE: . Upgraded to PCRE 8.34. (Anatol) +- Pgsql: + . Added warning for dangerous client encoding and remove possible injections + for pg_insert()/pg_update()/pg_delete()/pg_select(). (Yasuo) + + 06 Feb 2014, PHP 5.5.9 - Core: diff --git b/configure.in a/configure.in index 1f4080f..13ff75d 100644 --- b/configure.in +++ a/configure.in @@ -119,7 +119,7 @@ int zend_sprintf(char *buffer, const char *format, ...); PHP_MAJOR_VERSION=5 PHP_MINOR_VERSION=5 -PHP_RELEASE_VERSION=9 +PHP_RELEASE_VERSION=11 PHP_EXTRA_VERSION="-dev" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION` diff --git b/ext/fileinfo/libmagic.patch a/ext/fileinfo/libmagic.patch index 97e771e..d7fc532 100644 --- b/ext/fileinfo/libmagic.patch +++ a/ext/fileinfo/libmagic.patch @@ -1,6 +1,6 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c ---- libmagic.orig/apprentice.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/apprentice.c 2013-04-27 13:53:32.175250261 +0200 +--- libmagic.orig/apprentice.c Thu Mar 21 18:45:14 2013 ++++ libmagic/apprentice.c Fri May 3 15:19:35 2013 @@ -29,6 +29,8 @@ * apprentice - make one pass through /etc/magic, learning its secrets. */ @@ -830,8 +830,8 @@ diff -u libmagic.orig/apprentice.c libmagic/apprentice.c m->str_flags = swap4(m->str_flags); } diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c ---- libmagic.orig/ascmagic.c 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/ascmagic.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/ascmagic.c Wed Oct 31 18:03:01 2012 ++++ libmagic/ascmagic.c Tue Feb 18 18:44:17 2014 @@ -139,7 +139,7 @@ /* malloc size is a conservative overestimate; could be improved, or at least realloced after conversion. */ @@ -841,6 +841,15 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c file_oomem(ms, mlen); goto done; } +@@ -147,7 +147,7 @@ + == NULL) + goto done; + if ((rv = file_softmagic(ms, utf8_buf, +- (size_t)(utf8_end - utf8_buf), TEXTTEST, text)) == 0) ++ (size_t)(utf8_end - utf8_buf), 0, TEXTTEST, text)) == 0) + rv = -1; + } + @@ -211,6 +211,7 @@ case 0: if (file_printf(ms, ", ") == -1) @@ -860,8 +869,8 @@ diff -u libmagic.orig/ascmagic.c libmagic/ascmagic.c return rv; } diff -u libmagic.orig/cdf.c libmagic/cdf.c ---- libmagic.orig/cdf.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/cdf.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/cdf.c Thu Mar 21 18:45:14 2013 ++++ libmagic/cdf.c Sun Apr 7 22:30:22 2013 @@ -43,7 +43,17 @@ #include <err.h> #endif @@ -923,8 +932,8 @@ diff -u libmagic.orig/cdf.c libmagic/cdf.c (void)fprintf(stderr, "timestamp %s\n", buf); } else { diff -u libmagic.orig/cdf.h libmagic/cdf.h ---- libmagic.orig/cdf.h 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/cdf.h 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/cdf.h Wed Oct 31 18:03:01 2012 ++++ libmagic/cdf.h Sun Apr 7 22:30:22 2013 @@ -35,10 +35,12 @@ #ifndef _H_CDF_ #define _H_CDF_ @@ -966,8 +975,8 @@ diff -u libmagic.orig/cdf.h libmagic/cdf.h void cdf_swap_header(cdf_header_t *); void cdf_unpack_header(cdf_header_t *, char *); diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c ---- libmagic.orig/cdf_time.c 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/cdf_time.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/cdf_time.c Wed Oct 31 18:03:01 2012 ++++ libmagic/cdf_time.c Sun Apr 7 22:30:22 2013 @@ -96,7 +96,7 @@ } @@ -1026,8 +1035,8 @@ diff -u libmagic.orig/cdf_time.c libmagic/cdf_time.c static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL; static const char *ref = "Sat Apr 23 01:30:00 1977"; diff -u libmagic.orig/compress.c libmagic/compress.c ---- libmagic.orig/compress.c 2013-01-06 21:35:43.000000000 +0100 -+++ libmagic/compress.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/compress.c Sun Jan 6 21:35:43 2013 ++++ libmagic/compress.c Sun Apr 7 22:30:22 2013 @@ -32,6 +32,7 @@ * uncompress(method, old, n, newch) - uncompress old into new, * using method, return sizeof new @@ -1189,8 +1198,8 @@ diff -u libmagic.orig/compress.c libmagic/compress.c -#endif +#endif /* if PHP_FILEINFO_UNCOMPRESS */ diff -u libmagic.orig/file.h libmagic/file.h ---- libmagic.orig/file.h 2013-02-18 16:40:59.000000000 +0100 -+++ libmagic/file.h 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/file.h Mon Feb 18 16:40:59 2013 ++++ libmagic/file.h Tue Feb 18 18:44:17 2014 @@ -33,11 +33,9 @@ #ifndef __file_h__ #define __file_h__ @@ -1303,7 +1312,13 @@ diff -u libmagic.orig/file.h libmagic/file.h protected int file_zmagic(struct magic_set *, int, const char *, const unsigned char *, size_t); #endif -@@ -443,16 +442,13 @@ +@@ -438,21 +437,18 @@ + unichar **, size_t *, const char **, const char **, const char **); + protected int file_is_tar(struct magic_set *, const unsigned char *, size_t); + protected int file_softmagic(struct magic_set *, const unsigned char *, size_t, +- int, int); ++ size_t, int, int); + protected int file_apprentice(struct magic_set *, const char *, int); protected int file_magicfind(struct magic_set *, const char *, struct mlist *); protected uint64_t file_signextend(struct magic_set *, struct magic *, uint64_t); @@ -1377,22 +1392,24 @@ diff -u libmagic.orig/file.h libmagic/file.h #if defined(HAVE_MMAP) && defined(HAVE_SYS_MMAN_H) && !defined(QUICK) #define QUICK -@@ -533,4 +511,12 @@ - #define FILE_RCSID(id) +@@ -531,6 +509,14 @@ #endif - + #else + #define FILE_RCSID(id) ++#endif ++ +#ifdef PHP_WIN32 +#define FINFO_LSEEK_FUNC _lseek +#define FINFO_READ_FUNC _read +#else +#define FINFO_LSEEK_FUNC lseek +#define FINFO_READ_FUNC read -+#endif -+ + #endif + #endif /* __file_h__ */ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c ---- libmagic.orig/fsmagic.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/fsmagic.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/fsmagic.c Thu Mar 21 18:45:14 2013 ++++ libmagic/fsmagic.c Sun Apr 7 22:30:22 2013 @@ -59,27 +59,21 @@ # define minor(dev) ((dev) & 0xff) #endif @@ -1758,8 +1775,8 @@ diff -u libmagic.orig/fsmagic.c libmagic/fsmagic.c return ret; } diff -u libmagic.orig/funcs.c libmagic/funcs.c ---- libmagic.orig/funcs.c 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/funcs.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/funcs.c Wed Oct 31 18:03:01 2012 ++++ libmagic/funcs.c Tue Feb 18 18:44:17 2014 @@ -41,52 +41,42 @@ #if defined(HAVE_WCTYPE_H) #include <wctype.h> @@ -1896,7 +1913,7 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "zmagic %d\n", m); goto done; -@@ -219,12 +221,17 @@ +@@ -219,16 +221,21 @@ } /* Check if we have a CDF file */ @@ -1919,6 +1936,11 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c /* try soft magic tests */ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) +- if ((m = file_softmagic(ms, ubuf, nb, BINTEST, ++ if ((m = file_softmagic(ms, ubuf, nb, 0, BINTEST, + looks_text)) != 0) { + if ((ms->flags & MAGIC_DEBUG) != 0) + (void)fprintf(stderr, "softmagic %d\n", m); @@ -296,7 +303,6 @@ return m; @@ -2047,8 +2069,8 @@ diff -u libmagic.orig/funcs.c libmagic/funcs.c } + diff -u libmagic.orig/magic.c libmagic/magic.c ---- libmagic.orig/magic.c 2013-01-11 17:43:09.000000000 +0100 -+++ libmagic/magic.c 2013-04-27 13:53:32.175250261 +0200 +--- libmagic.orig/magic.c Fri Jan 11 17:43:09 2013 ++++ libmagic/magic.c Fri May 3 15:19:35 2013 @@ -25,11 +25,6 @@ * SUCH DAMAGE. */ @@ -2391,8 +2413,8 @@ diff -u libmagic.orig/magic.c libmagic/magic.c public const char * magic_error(struct magic_set *ms) diff -u libmagic.orig/magic.h libmagic/magic.h ---- libmagic.orig/magic.h 2013-03-21 18:52:42.000000000 +0100 -+++ libmagic/magic.h 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/magic.h Thu Mar 21 18:52:42 2013 ++++ libmagic/magic.h Sun Apr 7 22:30:22 2013 @@ -87,6 +87,7 @@ const char *magic_getpath(const char *, int); @@ -2410,15 +2432,15 @@ diff -u libmagic.orig/magic.h libmagic/magic.h int magic_errno(magic_t); diff -u libmagic.orig/print.c libmagic/print.c ---- libmagic.orig/print.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/print.c 2013-04-27 13:53:32.175250261 +0200 -@@ -28,13 +28,17 @@ - /* +--- libmagic.orig/print.c Thu Mar 21 18:45:14 2013 ++++ libmagic/print.c Mon Dec 16 23:09:24 2013 +@@ -29,12 +29,17 @@ * print.c - debugging printout routines */ + +#define _GNU_SOURCE +#include "php.h" - ++ #include "file.h" +#include "cdf.h" @@ -2430,7 +2452,7 @@ diff -u libmagic.orig/print.c libmagic/print.c #include <string.h> #include <stdarg.h> #include <stdlib.h> -@@ -43,188 +47,28 @@ +@@ -43,188 +48,28 @@ #endif #include <time.h> @@ -2631,7 +2653,7 @@ diff -u libmagic.orig/print.c libmagic/print.c } protected const char * -@@ -235,7 +79,7 @@ +@@ -235,7 +80,7 @@ struct tm *tm; if (flags & FILE_T_WINDOWS) { @@ -2641,8 +2663,8 @@ diff -u libmagic.orig/print.c libmagic/print.c t = ts.tv_sec; } diff -u libmagic.orig/readcdf.c libmagic/readcdf.c ---- libmagic.orig/readcdf.c 2012-10-31 18:03:01.000000000 +0100 -+++ libmagic/readcdf.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/readcdf.c Wed Oct 31 18:03:01 2012 ++++ libmagic/readcdf.c Sun Apr 7 22:30:22 2013 @@ -30,7 +30,11 @@ #endif @@ -2704,8 +2726,8 @@ diff -u libmagic.orig/readcdf.c libmagic/readcdf.c if (file_printf(ms, "application/CDFV2-corrupt") == -1) return -1; diff -u libmagic.orig/readelf.c libmagic/readelf.c ---- libmagic.orig/readelf.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/readelf.c 2013-04-08 15:42:57.328298809 +0200 +--- libmagic.orig/readelf.c Thu Mar 21 18:45:14 2013 ++++ libmagic/readelf.c Sun Apr 7 22:30:22 2013 @@ -48,8 +48,8 @@ private int dophn_exec(struct magic_set *, int, int, int, off_t, int, size_t, off_t, int *, int); @@ -2956,8 +2978,8 @@ diff -u libmagic.orig/readelf.c libmagic/readelf.c if (fstat(fd, &st) == -1) { diff -u libmagic.orig/readelf.h libmagic/readelf.h ---- libmagic.orig/readelf.h 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/readelf.h 2013-03-31 16:57:18.499744030 +0200 +--- libmagic.orig/readelf.h Thu Mar 21 18:45:14 2013 ++++ libmagic/readelf.h Wed Mar 28 15:35:26 2012 @@ -44,9 +44,17 @@ typedef uint32_t Elf32_Word; typedef uint8_t Elf32_Char; @@ -2977,8 +2999,8 @@ diff -u libmagic.orig/readelf.h libmagic/readelf.h typedef uint32_t Elf64_Word; typedef uint8_t Elf64_Char; diff -u libmagic.orig/softmagic.c libmagic/softmagic.c ---- libmagic.orig/softmagic.c 2013-03-21 18:45:14.000000000 +0100 -+++ libmagic/softmagic.c 2013-05-14 11:00:07.044745939 +0200 +--- libmagic.orig/softmagic.c Thu Mar 21 18:45:14 2013 ++++ libmagic/softmagic.c Tue Feb 18 18:44:17 2014 @@ -41,6 +41,11 @@ #include <stdlib.h> #include <time.h> @@ -2991,6 +3013,22 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c private int match(struct magic_set *, struct magic *, uint32_t, const unsigned char *, size_t, size_t, int, int, int, int, int *, int *, +@@ -69,13 +74,13 @@ + /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ + protected int + file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, +- int mode, int text) ++ size_t level, int mode, int text) + { + struct mlist *ml; + int rv, printed_something = 0, need_separator = 0; + for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) + if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode, +- text, 0, 0, &printed_something, &need_separator, ++ text, 0, level, &printed_something, &need_separator, + NULL)) != 0) + return rv; + @@ -132,7 +137,7 @@ struct magic *m = &magic[magindex]; @@ -3113,7 +3151,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } if (m->flag & INDIR) { -@@ -1644,9 +1624,6 @@ +@@ -1644,16 +1624,13 @@ if ((ms->flags & MAGIC_DEBUG) != 0) { mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); @@ -3123,7 +3161,32 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } } -@@ -1717,12 +1694,12 @@ + /* Verify we have enough data to match magic type */ + switch (m->type) { + case FILE_BYTE: +- if (nbytes < (offset + 1)) /* should alway be true */ ++ if (nbytes < (offset + 1)) /* should always be true */ + return 0; + break; + +@@ -1703,6 +1680,8 @@ + break; + + case FILE_INDIRECT: ++ if (offset == 0) ++ return 0; + if (nbytes < offset) + return 0; + sbuf = ms->o.buf; +@@ -1710,19 +1689,19 @@ + ms->o.buf = NULL; + ms->offset = 0; + rv = file_softmagic(ms, s + offset, nbytes - offset, +- BINTEST, text); ++ recursion_level, BINTEST, text); + if ((ms->flags & MAGIC_DEBUG) != 0) + fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); + rbuf = ms->o.buf; ms->o.buf = sbuf; ms->offset = soffset; if (rv == 1) { @@ -3139,7 +3202,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c } return rv; -@@ -1837,6 +1814,42 @@ +@@ -1837,6 +1816,42 @@ return file_strncmp(a, b, len, flags); } @@ -3182,7 +3245,7 @@ diff -u libmagic.orig/softmagic.c libmagic/softmagic.c private int magiccheck(struct magic_set *ms, struct magic *m) { -@@ -1996,69 +2009,157 @@ +@@ -1996,69 +2011,157 @@ break; } case FILE_REGEX: { diff --git b/ext/fileinfo/libmagic/ascmagic.c a/ext/fileinfo/libmagic/ascmagic.c index 2090097..c0041df 100644 --- b/ext/fileinfo/libmagic/ascmagic.c +++ a/ext/fileinfo/libmagic/ascmagic.c @@ -147,7 +147,7 @@ file_ascmagic_with_encoding(struct magic_set *ms, const unsigned char *buf, == NULL) goto done; if ((rv = file_softmagic(ms, utf8_buf, - (size_t)(utf8_end - utf8_buf), TEXTTEST, text)) == 0) + (size_t)(utf8_end - utf8_buf), 0, TEXTTEST, text)) == 0) rv = -1; } diff --git b/ext/fileinfo/libmagic/file.h a/ext/fileinfo/libmagic/file.h index 19b6872..ab5082d 100644 --- b/ext/fileinfo/libmagic/file.h +++ a/ext/fileinfo/libmagic/file.h @@ -437,7 +437,7 @@ protected int file_encoding(struct magic_set *, const unsigned char *, size_t, unichar **, size_t *, const char **, const char **, const char **); protected int file_is_tar(struct magic_set *, const unsigned char *, size_t); protected int file_softmagic(struct magic_set *, const unsigned char *, size_t, - int, int); + size_t, int, int); protected int file_apprentice(struct magic_set *, const char *, int); protected int file_magicfind(struct magic_set *, const char *, struct mlist *); protected uint64_t file_signextend(struct magic_set *, struct magic *, diff --git b/ext/fileinfo/libmagic/funcs.c a/ext/fileinfo/libmagic/funcs.c index 9c0d2bd..011ca42 100644 --- b/ext/fileinfo/libmagic/funcs.c +++ a/ext/fileinfo/libmagic/funcs.c @@ -235,7 +235,7 @@ file_buffer(struct magic_set *ms, php_stream *stream, const char *inname, const /* try soft magic tests */ if ((ms->flags & MAGIC_NO_CHECK_SOFT) == 0) - if ((m = file_softmagic(ms, ubuf, nb, BINTEST, + if ((m = file_softmagic(ms, ubuf, nb, 0, BINTEST, looks_text)) != 0) { if ((ms->flags & MAGIC_DEBUG) != 0) (void)fprintf(stderr, "softmagic %d\n", m); diff --git b/ext/fileinfo/libmagic/softmagic.c a/ext/fileinfo/libmagic/softmagic.c index 0671fa9..7c5f628 100644 --- b/ext/fileinfo/libmagic/softmagic.c +++ a/ext/fileinfo/libmagic/softmagic.c @@ -74,13 +74,13 @@ private void cvt_64(union VALUETYPE *, const struct magic *); /*ARGSUSED1*/ /* nbytes passed for regularity, maybe need later */ protected int file_softmagic(struct magic_set *ms, const unsigned char *buf, size_t nbytes, - int mode, int text) + size_t level, int mode, int text) { struct mlist *ml; int rv, printed_something = 0, need_separator = 0; for (ml = ms->mlist[0]->next; ml != ms->mlist[0]; ml = ml->next) if ((rv = match(ms, ml->magic, ml->nmagic, buf, nbytes, 0, mode, - text, 0, 0, &printed_something, &need_separator, + text, 0, level, &printed_something, &need_separator, NULL)) != 0) return rv; @@ -1680,6 +1680,8 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, break; case FILE_INDIRECT: + if (offset == 0) + return 0; if (nbytes < offset) return 0; sbuf = ms->o.buf; @@ -1687,7 +1689,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m, ms->o.buf = NULL; ms->offset = 0; rv = file_softmagic(ms, s + offset, nbytes - offset, - BINTEST, text); + recursion_level, BINTEST, text); if ((ms->flags & MAGIC_DEBUG) != 0) fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv); rbuf = ms->o.buf; diff --git b/ext/fileinfo/php_fileinfo.h a/ext/fileinfo/php_fileinfo.h index d8dec12..354ec7b 100644 --- b/ext/fileinfo/php_fileinfo.h +++ a/ext/fileinfo/php_fileinfo.h @@ -24,7 +24,7 @@ extern zend_module_entry fileinfo_module_entry; #define phpext_fileinfo_ptr &fileinfo_module_entry -#define PHP_FILEINFO_VERSION "1.0.5-dev" +#define PHP_FILEINFO_VERSION "1.0.5" #ifdef PHP_WIN32 #define PHP_FILEINFO_API __declspec(dllexport) diff --git b/ext/fileinfo/tests/cve-2014-1943.phpt a/ext/fileinfo/tests/cve-2014-1943.phpt new file mode 100644 index 0000000..b2e9c17 --- /dev/null +++ a/ext/fileinfo/tests/cve-2014-1943.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #66731: file: infinite recursion +--SKIPIF-- +<?php +if (!class_exists('finfo')) + die('skip no fileinfo extension'); +--FILE-- +<?php +$fd = __DIR__.'/cve-2014-1943.data'; +$fm = __DIR__.'/cve-2014-1943.magic'; + +$a = "\105\122\000\000\000\000\000"; +$b = str_repeat("\001", 250000); +$m = "0 byte x\n". + ">(1.b) indirect x\n"; + +file_put_contents($fd, $a); +$fi = finfo_open(FILEINFO_NONE); +var_dump(finfo_file($fi, $fd)); +finfo_close($fi); + +file_put_contents($fd, $b); +file_put_contents($fm, $m); +$fi = finfo_open(FILEINFO_NONE, $fm); +var_dump(finfo_file($fi, $fd)); +finfo_close($fi); +?> +Done +--CLEAN-- +<?php +@unlink(__DIR__.'/cve-2014-1943.data'); +@unlink(__DIR__.'/cve-2014-1943.magic'); +?> +--EXPECTF-- +string(%d) "%s" + +Warning: finfo_file(): Failed identify data 0:(null) in %s on line %d +bool(false) +Done diff --git b/ext/json/json.c a/ext/json/json.c index 4ab6278..b0191c3 100644 --- b/ext/json/json.c +++ a/ext/json/json.c @@ -39,7 +39,7 @@ static PHP_FUNCTION(json_last_error_msg); static const char digits[] = "0123456789abcdef"; -zend_class_entry *php_json_serializable_ce; +PHP_JSON_API zend_class_entry *php_json_serializable_ce; ZEND_DECLARE_MODULE_GLOBALS(json) diff --git b/ext/json/php_json.h a/ext/json/php_json.h index 637c5ea..e00de6a 100644 --- b/ext/json/php_json.h +++ a/ext/json/php_json.h @@ -51,7 +51,7 @@ ZEND_END_MODULE_GLOBALS(json) PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC); PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len, int options, long depth TSRMLS_DC); -extern zend_class_entry *php_json_serializable_ce; +extern PHP_JSON_API zend_class_entry *php_json_serializable_ce; /* json_encode() options */ diff --git b/ext/openssl/openssl.c a/ext/openssl/openssl.c old mode 100644 new mode 100755 index 3d73751..f1e582b --- b/ext/openssl/openssl.c +++ a/ext/openssl/openssl.c @@ -3026,7 +3026,7 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC) } break; #endif -#ifdef EVP_PKEY_EC +#if OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_EC) && defined(EVP_PKEY_EC) case EVP_PKEY_EC: assert(pkey->pkey.ec != NULL); @@ -3435,7 +3435,7 @@ PHP_FUNCTION(openssl_pkey_get_details) } break; -#ifdef EVP_PKEY_EC +#ifdef EVP_PKEY_EC case EVP_PKEY_EC: ktype = OPENSSL_KEYTYPE_EC; break; diff --git b/ext/pgsql/pgsql.c a/ext/pgsql/pgsql.c index b37f40a..be915ae 100644 --- b/ext/pgsql/pgsql.c +++ a/ext/pgsql/pgsql.c @@ -15,8 +15,8 @@ | Authors: Zeev Suraski <zeev@zend.com> | | Jouni Ahto <jouni.ahto@exdec.fi> | | Yasuo Ohgaki <yohgaki@php.net> | - | Youichi Iwakiri <yiwakiri@st.rim.or.jp> (pg_copy_*) | - | Chris Kings-Lynne <chriskl@php.net> (v3 protocol) | + | Youichi Iwakiri <yiwakiri@st.rim.or.jp> (pg_copy_*) | + | Chris Kings-Lynne <chriskl@php.net> (v3 protocol) | +----------------------------------------------------------------------+ */ @@ -746,6 +746,105 @@ ZEND_GET_MODULE(pgsql) static int le_link, le_plink, le_result, le_lofp, le_string; +/* Compatibility definitions */ + +#ifndef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT +#define pg_encoding_to_char(x) "SQL_ASCII" +#endif + +#if !HAVE_PQESCAPE_CONN +#define PQescapeStringConn(conn, to, form, len, error) PQescapeString(to, from, len) +#endif + +#if HAVE_PQESCAPELITERAL +#define PGSQLescapeLiteral(conn, str, len) PQescapeLiteral(conn, str, len) +#define PGSQLescapeIdentifier(conn, str, len) PQescapeIdentifier(conn, str, len) +#define PGSQLfree(a) PQfreemem(a) +#else +#define PGSQLescapeLiteral(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 0) +#define PGSQLescapeLiteral2(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 1, 1) +#define PGSQLescapeIdentifier(conn, str, len) php_pgsql_PQescapeInternal(conn, str, len, 0, 0) +#define PGSQLfree(a) efree(a) + +/* emulate libpq's PQescapeInternal() 9.0 or later */ +static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal, int safe) { + char *result, *rp, *s; + size_t tmp_len; + + if (!conn) { + return NULL; + } + + /* allocate enough memory */ + rp = result = (char *)safe_emalloc(len, 2, 5); /* leading " E" needs extra 2 bytes + quote_chars on both end for 2 bytes + NULL */ + + if (escape_literal) { + size_t new_len; + + if (safe) { + char *tmp = (char *)safe_emalloc(len, 2, 1); + *rp++ = '\''; + /* PQescapeString does not escape \, but it handles multibyte chars safely. + This escape is incompatible with PQescapeLiteral. */ + new_len = PQescapeStringConn(conn, tmp, str, len, NULL); + strncpy(rp, tmp, new_len); + efree(tmp); + rp += new_len; + } else { + char *encoding; + /* This is compatible with PQescapeLiteral, but it cannot handle multbyte chars + such as SJIS, BIG5. Raise warning and return NULL by checking + client_encoding. */ + encoding = (char *) pg_encoding_to_char(PQclientEncoding(conn)); + if (!strncmp(encoding, "SJIS", sizeof("SJIS")-1) || + !strncmp(encoding, "SHIFT_JIS_2004", sizeof("SHIFT_JIS_2004")-1) || + !strncmp(encoding, "BIG5", sizeof("BIG5")-1) || + !strncmp(encoding, "GB18030", sizeof("GB18030")-1) || + !strncmp(encoding, "GBK", sizeof("GBK")-1) || + !strncmp(encoding, "JOHAB", sizeof("JOHAB")-1) || + !strncmp(encoding, "UHC", sizeof("UHC")-1) ) { + TSRMLS_FETCH(); + + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsafe encoding is used. Do not use '%s' encoding or use PostgreSQL 9.0 or later libpq.", encoding); + } + /* check backslashes */ + tmp_len = strspn(str, "\\"); + if (tmp_len != len) { + /* add " E" for escaping slashes */ + *rp++ = ' '; + *rp++ = 'E'; + } + *rp++ = '\''; + for (s = (char *)str; s - str < len; ++s) { + if (*s == '\'' || *s == '\\') { + *rp++ = *s; + *rp++ = *s; + } else { + *rp++ = *s; + } + } + } + *rp++ = '\''; + } else { + /* Identifier escape. */ + *rp++ = '"'; + for (s = (char *)str; s - str < len; ++s) { + if (*s == '"') { + *rp++ = '"'; + *rp++ = '"'; + } else { + *rp++ = *s; + } + } + *rp++ = '"'; + } + *rp = '\0'; + + return result; +} +#endif + + /* {{{ _php_pgsql_trim_message */ static char * _php_pgsql_trim_message(const char *message, int *len) { @@ -774,16 +873,16 @@ static inline char * _php_pgsql_trim_result(PGconn * pgsql, char **buf) #define PQErrorMessageTrim(pgsql, buf) _php_pgsql_trim_result(pgsql, buf) -#define PHP_PQ_ERROR(text, pgsql) { \ - char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); \ - php_error_docref(NULL TSRMLS_CC, E_WARNING, text, msgbuf); \ - efree(msgbuf); \ +#define PHP_PQ_ERROR(text, pgsql) { \ + char *msgbuf = _php_pgsql_trim_message(PQerrorMessage(pgsql), NULL); \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, text, msgbuf); \ + efree(msgbuf); \ } \ /* {{{ php_pgsql_set_default_link */ static void php_pgsql_set_default_link(int id TSRMLS_DC) -{ +{ zend_list_addref(id); if (PGG(default_link) != -1) { @@ -851,10 +950,10 @@ static void _php_pgsql_notice_ptr_dtor(void **ptr) { php_pgsql_notice *notice = (php_pgsql_notice *)*ptr; if (notice) { - efree(notice->message); - efree(notice); - notice = NULL; - } + efree(notice->message); + efree(notice); + notice = NULL; + } } /* }}} */ @@ -944,57 +1043,7 @@ static int _php_pgsql_detect_identifier_escape(const char *identifier, size_t le return SUCCESS; } -#if !HAVE_PQESCAPELITERAL -/* {{{ _php_pgsql_escape_identifier - * Since PQescapeIdentifier() is unavailable (PostgreSQL 9.0 <), idenfifers - * should be escaped by pgsql module. - * Note: this function does not care for encoding. Therefore users should not - * use this with SJIS/BIG5 etc. (i.e. Encoding base injection may possible with - * before PostgreSQL 9.0) - */ -static char *_php_pgsql_escape_identifier(const char *field, size_t field_len) -{ - ulong field_escaped_len = field_len*2 + 3; - ulong i, j = 0; - char *field_escaped; - - field_escaped = (char *)malloc(field_escaped_len); - field_escaped[j++] = '"'; - for (i = 0; i < field_len; i++) { - if (field[i] == '"') { - field_escaped[j++] = '"'; - field_escaped[j++] = '"'; - } else { - field_escaped[j++] = field[i]; - } - } - field_escaped[j++] = '"'; - field_escaped[j] = '\0'; - return field_escaped; -} -/* }}} */ -#endif - -/* {{{ _php_pgsql_strndup, no strndup should be used */ -static char *_php_pgsql_strndup(const char *s, size_t len) -{ - char *new; - if (NULL == s) { - return (char *)NULL; - } - - new = (char *) malloc(len + 1); - - if (NULL == new) { - return (char *)NULL; - } - - new[len] = '\0'; - - return memmove(new, s, len); -} -/* }}} */ /* {{{ PHP_INI */ @@ -1023,7 +1072,7 @@ static PHP_GINIT_FUNCTION(pgsql) PHP_MINIT_FUNCTION(pgsql) { REGISTER_INI_ENTRIES(); - + le_link = zend_register_list_destructors_ex(_close_pgsql_link, NULL, "pgsql link", module_number); le_plink = zend_register_list_destructors_ex(NULL, _close_pgsql_plink, "pgsql link persistent", module_number); le_result = zend_register_list_destructors_ex(_free_result, NULL, "pgsql result", module_number); @@ -1159,7 +1208,7 @@ PHP_MINFO_FUNCTION(pgsql) #else php_info_print_table_row(2, "SSL support", "disabled"); #endif -#endif /* HAVE_PG_CONFIG_H */ +#endif /* HAVE_PG_CONFIG_H */ snprintf(buf, sizeof(buf), "%ld", PGG(num_persistent)); php_info_print_table_row(2, "Active Persistent Links", buf); snprintf(buf, sizeof(buf), "%ld", PGG(num_links)); @@ -1227,7 +1276,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) break; } } - + if (persistent && PGG(allow_persistent)) { zend_rsrc_list_entry *le; @@ -1310,7 +1359,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) ZEND_REGISTER_RESOURCE(return_value, pgsql, le_plink); } else { /* Non persistent connection */ zend_rsrc_list_entry *index_ptr,new_index_ptr; - + /* first we check the hash for the hashed_details key. if it exists, * it should point us to the right offset where the actual pgsql link sits. * if it doesn't, open a new pgsql link, add it to the resource list, @@ -1374,7 +1423,7 @@ static void php_pgsql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) cleanup: smart_str_free(&str); return; - + err: smart_str_free(&str); RETURN_FALSE; @@ -1418,11 +1467,11 @@ PHP_FUNCTION(pg_close) zval *pgsql_link = NULL; int id = -1, argc = ZEND_NUM_ARGS(); PGconn *pgsql; - + if (zend_parse_parameters(argc TSRMLS_CC, "|r", &pgsql_link) == FAILURE) { return; } - + if (argc == 0) { id = PGG(default_link); CHECK_DEFAULT_LINK(id); @@ -1430,7 +1479,7 @@ PHP_FUNCTION(pg_close) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1438,7 +1487,7 @@ PHP_FUNCTION(pg_close) zend_list_delete(Z_RESVAL_P(pgsql_link)); } - if (id!=-1 + if (id!=-1 || (pgsql_link && Z_RESVAL_P(pgsql_link)==PGG(default_link))) { zend_list_delete(PGG(default_link)); PGG(default_link) = -1; @@ -1457,6 +1506,7 @@ PHP_FUNCTION(pg_close) #define PHP_PG_HOST 6 #define PHP_PG_VERSION 7 + /* {{{ php_pgsql_get_link_info */ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) @@ -1477,7 +1527,7 @@ static void php_pgsql_get_link_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1603,7 +1653,7 @@ PHP_FUNCTION(pg_parameter_status) } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1634,7 +1684,7 @@ PHP_FUNCTION(pg_ping) } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1709,7 +1759,7 @@ PHP_FUNCTION(pg_query) } else { status = (ExecStatusType) PQstatus(pgsql); } - + switch (status) { case PGRES_EMPTY_QUERY: case PGRES_BAD_RESPONSE: @@ -1805,7 +1855,7 @@ PHP_FUNCTION(pg_query_params) if (num_params > 0) { int i = 0; params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - + for(i = 0; i < num_params; i++) { if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); @@ -1902,10 +1952,10 @@ PHP_FUNCTION(pg_prepare) return; } } - + if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -1932,7 +1982,7 @@ PHP_FUNCTION(pg_prepare) } else { status = (ExecStatusType) PQstatus(pgsql); } - + switch (status) { case PGRES_EMPTY_QUERY: case PGRES_BAD_RESPONSE: @@ -2012,7 +2062,7 @@ PHP_FUNCTION(pg_execute) if (num_params > 0) { int i = 0; params = (char **)safe_emalloc(sizeof(char *), num_params, 0); - + for(i = 0; i < num_params; i++) { if (zend_hash_get_current_data(Z_ARRVAL_P(pv_param_arr), (void **) &tmp) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error getting parameter"); @@ -2054,7 +2104,7 @@ PHP_FUNCTION(pg_execute) } else { status = (ExecStatusType) PQstatus(pgsql); } - + _php_pgsql_free_params(params, num_params); switch (status) { @@ -2206,7 +2256,7 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) num_rows = PQntuples(result); oid_offset = PQfnumber(result,"oid"); name_offset = PQfnumber(result,"typname"); - + for (i=0; i<num_rows; i++) { if ((tmp_oid = PQgetvalue(result,i,oid_offset))==NULL) { continue; @@ -2216,7 +2266,7 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) smart_str_appends(&str, "pgsql_oid_"); smart_str_appends(&str, tmp_oid); smart_str_0(&str); - + if ((tmp_name = PQgetvalue(result,i,name_offset))==NULL) { continue; } @@ -2233,7 +2283,7 @@ static char *get_field_name(PGconn *pgsql, Oid oid, HashTable *list TSRMLS_DC) smart_str_free(&str); return ret; } -/* }}} */ +/* }}} */ #ifdef HAVE_PQFTABLE /* {{{ proto mixed pg_field_table(resource result, int field_number[, bool oid_only]) @@ -2266,7 +2316,6 @@ PHP_FUNCTION(pg_field_table) RETURN_FALSE; } - if (return_oid) { #if UINT_MAX > LONG_MAX /* Oid is unsigned int, we don't need this code, where LONG is wider */ if (oid > LONG_MAX) { @@ -2296,7 +2345,6 @@ PHP_FUNCTION(pg_field_table) smart_str_append_unsigned(&querystr, oid); smart_str_0(&querystr); - if ((tmp_res = PQexec(pg_result->conn, querystr.c)) == NULL || PQresultStatus(tmp_res) != PGRES_TUPLES_OK) { if (tmp_res) { PQclear(tmp_res); @@ -2324,8 +2372,8 @@ PHP_FUNCTION(pg_field_table) } } -/* }}} */ -#endif +/* }}} */ +#endif #define PHP_PG_FIELD_NAME 1 #define PHP_PG_FIELD_SIZE 2 @@ -2341,11 +2389,11 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ PGresult *pgsql_result; pgsql_result_handle *pg_result; Oid oid; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) { return; } - + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; @@ -2354,7 +2402,7 @@ static void php_pgsql_get_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_typ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset specified"); RETURN_FALSE; } - + switch (entry_type) { case PHP_PG_FIELD_NAME: Z_STRVAL_P(return_value) = PQfname(pgsql_result, field); @@ -2441,11 +2489,11 @@ PHP_FUNCTION(pg_field_num) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &result, &field, &field_len) == FAILURE) { return; } - + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; - + Z_LVAL_P(return_value) = PQfnumber(pgsql_result, field); Z_TYPE_P(return_value) = IS_LONG; } @@ -2460,7 +2508,7 @@ PHP_FUNCTION(pg_fetch_result) PGresult *pgsql_result; pgsql_result_handle *pg_result; int field_offset, pgsql_row, argc = ZEND_NUM_ARGS(); - + if (argc == 2) { if (zend_parse_parameters(argc TSRMLS_CC, "rZ", &result, &field) == FAILURE) { return; @@ -2503,7 +2551,7 @@ PHP_FUNCTION(pg_fetch_result) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified"); RETURN_FALSE; } - + if (PQgetisnull(pgsql_result, pgsql_row, field_offset)) { Z_TYPE_P(return_value) = IS_NULL; } else { @@ -2606,12 +2654,12 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, data = safe_estrndup(element, element_len); data_len = element_len; - + if (result_type & PGSQL_NUM) { add_index_stringl(return_value, i, data, data_len, should_copy); should_copy=1; } - + if (result_type & PGSQL_ASSOC) { field_name = PQfname(pgsql_result, i); add_assoc_stringl(return_value, field_name, data, data_len, should_copy); @@ -2624,11 +2672,11 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, zval dataset = *return_value; zend_fcall_info fci; zend_fcall_info_cache fcc; - zval *retval_ptr; - + zval *retval_ptr; + object_and_properties_init(return_value, ce, NULL); zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC); - + if (ce->constructor) { fci.size = sizeof(fci); fci.function_table = &ce->function_table; @@ -2640,7 +2688,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, if (Z_TYPE_P(ctor_params) == IS_ARRAY) { HashTable *ht = Z_ARRVAL_P(ctor_params); Bucket *p; - + fci.param_count = 0; fci.params = safe_emalloc(sizeof(zval***), ht->nNumOfElements, 0); p = ht->pListHead; @@ -2669,7 +2717,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, fcc.calling_scope = EG(scope); fcc.called_scope = Z_OBJCE_P(return_value); fcc.object_ptr = return_value; - + if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) { zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name); } else { @@ -2775,7 +2823,7 @@ PHP_FUNCTION(pg_fetch_all_columns) array_init(return_value); - if ((pg_numrows = PQntuples(pgsql_result)) <= 0) { + if ((pg_numrows = PQntuples(pgsql_result)) <= 0) { return; } @@ -2784,7 +2832,7 @@ PHP_FUNCTION(pg_fetch_all_columns) add_next_index_null(return_value); } else { add_next_index_string(return_value, PQgetvalue(pgsql_result, pg_row, colno), 1); - } + } } } /* }}} */ @@ -2806,7 +2854,7 @@ PHP_FUNCTION(pg_result_seek) if (row < 0 || row >= PQntuples(pg_result->result)) { RETURN_FALSE; } - + /* seek to offset */ pg_result->row = row; RETURN_TRUE; @@ -2836,7 +2884,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) return; } } - + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; @@ -2856,7 +2904,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) RETURN_FALSE; } } - + switch(Z_TYPE_PP(field)) { case IS_STRING: convert_to_string_ex(field); @@ -2871,7 +2919,7 @@ static void php_pgsql_data_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified"); RETURN_FALSE; } - + switch (entry_type) { case PHP_PG_DATA_LENGTH: Z_LVAL_P(return_value) = PQgetlength(pgsql_result, pgsql_row, field_offset); @@ -2906,7 +2954,7 @@ PHP_FUNCTION(pg_free_result) { zval *result; pgsql_result_handle *pg_result; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { return; } @@ -2934,7 +2982,7 @@ PHP_FUNCTION(pg_last_oid) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) { return; } - + ZEND_FETCH_RESOURCE(pg_result, pgsql_result_handle *, &result, -1, "PostgreSQL result", le_result); pgsql_result = pg_result->result; #ifdef HAVE_PQOIDVALUE @@ -2965,18 +3013,18 @@ PHP_FUNCTION(pg_trace) FILE *fp = NULL; php_stream *stream; id = PGG(default_link); - + if (zend_parse_parameters(argc TSRMLS_CC, "s|sr", &z_filename, &z_filename_len, &mode, &mode_len, &pgsql_link) == FAILURE) { return; } if (argc < 3) { CHECK_DEFAULT_LINK(id); - } + } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3015,7 +3063,7 @@ PHP_FUNCTION(pg_untrace) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); PQuntrace(pgsql); @@ -3027,10 +3075,10 @@ PHP_FUNCTION(pg_untrace) Create a large object */ PHP_FUNCTION(pg_lo_create) { - zval *pgsql_link = NULL, *oid = NULL; - PGconn *pgsql; - Oid pgsql_oid, wanted_oid = InvalidOid; - int id = -1, argc = ZEND_NUM_ARGS(); + zval *pgsql_link = NULL, *oid = NULL; + PGconn *pgsql; + Oid pgsql_oid, wanted_oid = InvalidOid; + int id = -1, argc = ZEND_NUM_ARGS(); if (zend_parse_parameters(argc TSRMLS_CC, "|zz", &pgsql_link, &oid) == FAILURE) { return; @@ -3052,12 +3100,12 @@ PHP_FUNCTION(pg_lo_create) ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); if (oid) { -#ifndef HAVE_PG_LO_CREATE - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "OID value passing not supported"); +#ifndef HAVE_PG_LO_CREATE + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Passing OID value is not supported. Upgrade your PostgreSQL"); #else switch (Z_TYPE_P(oid)) { case IS_STRING: - { + { char *end_ptr; wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10); if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) { @@ -3083,7 +3131,7 @@ PHP_FUNCTION(pg_lo_create) RETURN_FALSE; } - PGSQL_RETURN_OID(pgsql_oid); + PGSQL_RETURN_OID(pgsql_oid); #endif } @@ -3092,7 +3140,7 @@ PHP_FUNCTION(pg_lo_create) RETURN_FALSE; } - PGSQL_RETURN_OID(pgsql_oid); + PGSQL_RETURN_OID(pgsql_oid); } /* }}} */ @@ -3154,7 +3202,7 @@ PHP_FUNCTION(pg_lo_unlink) } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3226,7 +3274,7 @@ PHP_FUNCTION(pg_lo_open) } if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3318,8 +3366,8 @@ PHP_FUNCTION(pg_lo_close) Read a large object */ PHP_FUNCTION(pg_lo_read) { - zval *pgsql_id; - long len; + zval *pgsql_id; + long len; int buf_len = PGSQL_LO_READ_BUF_SIZE, nbytes, argc = ZEND_NUM_ARGS(); char *buf; pgLofp *pgsql; @@ -3446,7 +3494,7 @@ PHP_FUNCTION(pg_lo_import) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3457,7 +3505,7 @@ PHP_FUNCTION(pg_lo_import) Oid wanted_oid; switch (Z_TYPE_P(oid)) { case IS_STRING: - { + { char *end_ptr; wanted_oid = (Oid)strtoul(Z_STRVAL_P(oid), &end_ptr, 10); if ((Z_STRVAL_P(oid)+Z_STRLEN_P(oid)) != end_ptr) { @@ -3579,13 +3627,13 @@ PHP_FUNCTION(pg_lo_export) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); if (lo_export(pgsql, oid, file_out)) { RETURN_TRUE; - } + } RETURN_FALSE; } /* }}} */ @@ -3700,7 +3748,7 @@ PHP_FUNCTION(pg_set_client_encoding) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3734,10 +3782,6 @@ PHP_FUNCTION(pg_client_encoding) /* Just do the same as found in PostgreSQL sources... */ -#ifndef HAVE_PGSQL_WITH_MULTIBYTE_SUPPORT -#define pg_encoding_to_char(x) "SQL_ASCII" -#endif - Z_STRVAL_P(return_value) = (char *) pg_encoding_to_char(PQclientEncoding(pgsql)); Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value)); Z_STRVAL_P(return_value) = (char *) estrdup(Z_STRVAL_P(return_value)); @@ -3770,7 +3814,7 @@ PHP_FUNCTION(pg_end_copy) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -3906,7 +3950,7 @@ PHP_FUNCTION(pg_copy_to) PHP_PQ_ERROR("getline failed: %s", pgsql); RETURN_FALSE; } - + if (copybuf[0] == '\\' && copybuf[1] == '.' && copybuf[2] == '\0') @@ -4114,12 +4158,11 @@ PHP_FUNCTION(pg_escape_string) } to = (char *) safe_emalloc(from_len, 2, 1); - #ifdef HAVE_PQESCAPE_CONN if (pgsql_link != NULL || id != -1) { ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); to_len = (int) PQescapeStringConn(pgsql, to, from, (size_t)from_len, NULL); - } else + } else #endif to_len = (int) PQescapeString(to, from, (size_t)from_len); @@ -4194,7 +4237,7 @@ PHP_FUNCTION(pg_escape_bytea) */ static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t *retbuflen) { - size_t buflen; + size_t buflen; unsigned char *buffer, *sp, *bp; @@ -4254,7 +4297,7 @@ static unsigned char * php_pgsql_unescape_bytea(unsigned char *strtext, size_t * memcpy(buf, sp-2, 3); buf[3] = '\0'; start = buf; - *bp = (unsigned char)strtoul(start, (char **)&end, 8); + *bp = (unsigned char)strtoul(start, (char **)&end, 8); buflen -= 3; state = 0; } @@ -4303,61 +4346,13 @@ PHP_FUNCTION(pg_unescape_bytea) #endif #ifdef HAVE_PQESCAPE -#if !HAVE_PQESCAPELITERAL -/* emulate libpq's PQescapeInternal() 9.0 or later */ -static char* php_pgsql_PQescapeInternal(PGconn *conn, const char *str, size_t len, int escape_literal) { - char *result, *rp; - const char *s; - size_t tmp_len; - int input_len = len; - char quote_char = escape_literal ? '\'' : '"'; - - if (!conn) { - return NULL; - } - - /* - * NOTE: multibyte strings that could cointain slashes should be considered. - * (e.g. SJIS, BIG5) However, it cannot be done without valid PGconn and mbstring. - * Therefore, this function does not support such encodings currently. - * FIXME: add encoding check and skip multibyte char bytes if there is vaild PGconn. - */ - - /* allocate enough memory */ - rp = result = (char *)emalloc(len*2 + 5); /* leading " E" needs extra 2 bytes + quote_chars on both end for 2 bytes + NULL */ - - if (escape_literal) { - /* check backslashes */ - tmp_len = strspn(str, "\\"); - if (tmp_len != len) { - /* add " E" for escaping slashes */ - *rp++ = ' '; - *rp++ = 'E'; - } - } - /* open quote */ - *rp++ = quote_char; - for (s = str; s - str < input_len; ++s) { - if (*s == quote_char || (escape_literal && *s == '\\')) { - *rp++ = *s; - *rp++ = *s; - } else { - *rp++ = *s; - } - } - *rp++ = quote_char; - *rp = '\0'; - - return result; -} -#endif - static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_literal) { char *from = NULL, *to = NULL; zval *pgsql_link = NULL; PGconn *pgsql; int from_len; int id = -1; + char *tmp; switch (ZEND_NUM_ARGS()) { case 1: @@ -4385,30 +4380,18 @@ static void php_pgsql_escape_internal(INTERNAL_FUNCTION_PARAMETERS, int escape_l php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot get pgsql link"); RETURN_FALSE; } -#ifdef HAVE_PQESCAPELITERAL - /* Use a block with a local var to avoid unused variable warnings */ - { - char *tmp; - if (escape_literal) { - tmp = PQescapeLiteral(pgsql, from, (size_t)from_len); - } else { - tmp = PQescapeIdentifier(pgsql, from, (size_t)from_len); - } - if (!tmp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING,"Failed to escape"); - RETURN_FALSE; - } - to = estrdup(tmp); - PQfreemem(tmp); + if (escape_literal) { + tmp = PGSQLescapeLiteral(pgsql, from, (size_t)from_len); + } else { + tmp = PGSQLescapeIdentifier(pgsql, from, (size_t)from_len); } -#else - to = php_pgsql_PQescapeInternal(pgsql, from, (size_t)from_len, escape_literal); - if (!to) { + if (!tmp) { php_error_docref(NULL TSRMLS_CC, E_WARNING,"Failed to escape"); RETURN_FALSE; } -#endif + to = estrdup(tmp); + PGSQLfree(tmp); RETURN_STRING(to, 0); } @@ -4456,6 +4439,7 @@ PHP_FUNCTION(pg_result_error) } /* }}} */ + #if HAVE_PQRESULTERRORFIELD /* {{{ proto string pg_result_error_field(resource result, int fieldcode) Get error message field associated with result */ @@ -4501,6 +4485,7 @@ PHP_FUNCTION(pg_result_error_field) /* }}} */ #endif + /* {{{ proto int pg_connection_status(resource connection) Get connection status */ PHP_FUNCTION(pg_connection_status) @@ -4521,6 +4506,7 @@ PHP_FUNCTION(pg_connection_status) /* }}} */ + #if HAVE_PGTRANSACTIONSTATUS /* {{{ proto int pg_transaction_status(resource connection) Get transaction status */ @@ -4543,6 +4529,7 @@ PHP_FUNCTION(pg_transaction_status) /* }}} */ + /* {{{ proto bool pg_connection_reset(resource connection) Reset connection (reconnect) */ PHP_FUNCTION(pg_connection_reset) @@ -4564,12 +4551,13 @@ PHP_FUNCTION(pg_connection_reset) } RETURN_TRUE; } - /* }}} */ + #define PHP_PG_ASYNC_IS_BUSY 1 #define PHP_PG_ASYNC_REQUEST_CANCEL 2 - + + /* {{{ php_pgsql_flush_query */ static int php_pgsql_flush_query(PGconn *pgsql TSRMLS_DC) @@ -4589,7 +4577,8 @@ static int php_pgsql_flush_query(PGconn *pgsql TSRMLS_DC) return leftover; } /* }}} */ - + + /* {{{ php_pgsql_do_async */ static void php_pgsql_do_async(INTERNAL_FUNCTION_PARAMETERS, int entry_type) @@ -4819,7 +4808,7 @@ PHP_FUNCTION(pg_send_prepare) if (pgsql_link == NULL && id == -1) { RETURN_FALSE; - } + } ZEND_FETCH_RESOURCE2(pgsql, PGconn *, &pgsql_link, id, "PostgreSQL link", le_link, le_plink); @@ -5107,7 +5096,7 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z size_t new_len; int i, num_rows; zval *elem; - + if (!*table_name) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The table name must be specified"); return FAILURE; @@ -5127,25 +5116,17 @@ PHP_PGSQL_API int php_pgsql_meta_data(PGconn *pg_link, const char *table_name, z "FROM pg_class as c, pg_attribute a, pg_type t, pg_namespace n " "WHERE a.attnum > 0 AND a.attrelid = c.oid AND c.relname = '"); escaped = (char *)safe_emalloc(strlen(tmp_name2), 2, 1); -#if HAVE_PQESCAPE_CONN new_len = PQescapeStringConn(pg_link, escaped, tmp_name2, strlen(tmp_name2), NULL); -#else - new_len = PQescapeString(escaped, tmp_name2, strlen(tmp_name2)); -#endif if (new_len) { - smart_str_appends(&querystr, escaped); + smart_str_appendl(&querystr, escaped, new_len); } efree(escaped); smart_str_appends(&querystr, "' AND c.relnamespace = n.oid AND n.nspname = '"); escaped = (char *)safe_emalloc(strlen(tmp_name), 2, 1); -#if HAVE_PQESCAPE_CONN new_len = PQescapeStringConn(pg_link, escaped, tmp_name, strlen(tmp_name), NULL); -#else - new_len = PQescapeString(escaped, tmp_name, strlen(tmp_name)); -#endif if (new_len) { - smart_str_appends(&querystr, escaped); + smart_str_appendl(&querystr, escaped, new_len); } efree(escaped); @@ -5208,7 +5189,7 @@ PHP_FUNCTION(pg_meta_data) uint table_name_len; PGconn *pgsql; int id = -1; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &pgsql_link, &table_name, &table_name_len) == FAILURE) { return; @@ -5235,13 +5216,14 @@ PHP_FUNCTION(pg_meta_data) } /* }}} */ + /* {{{ php_pgsql_get_data_type */ static php_pgsql_data_type php_pgsql_get_data_type(const char *type_name, size_t len) { - /* This is stupid way to do. I'll fix it when I decied how to support + /* This is stupid way to do. I'll fix it when I decied how to support user defined types. (Yasuo) */ - + /* boolean */ if (!strcmp(type_name, "bool")|| !strcmp(type_name, "boolean")) return PG_BOOL; @@ -5320,25 +5302,35 @@ static php_pgsql_data_type php_pgsql_get_data_type(const char *type_name, size_t return PG_POLYGON; if (!strcmp(type_name, "circle")) return PG_CIRCLE; - + return PG_UNKNOWN; } /* }}} */ /* {{{ php_pgsql_convert_match - * test field value with regular expression specified. + * test field value with regular expression specified. */ -static int php_pgsql_convert_match(const char *str, const char *regex , int icase TSRMLS_DC) +static int php_pgsql_convert_match(const char *str, size_t str_len, const char *regex , int icase TSRMLS_DC) { - regex_t re; + regex_t re; regmatch_t *subs; int regopt = REG_EXTENDED; int regerr, ret = SUCCESS; + int i; + + /* Check invalid chars for POSIX regex */ + for (i = 0; i < str_len; i++) { + if (str[i] == '\n' || + str[i] == '\r' || + str[i] == '\0' ) { + return FAILURE; + } + } if (icase) { regopt |= REG_ICASE; } - + regerr = regcomp(&re, regex, regopt); if (regerr) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot compile regex"); @@ -5349,7 +5341,7 @@ static int php_pgsql_convert_match(const char *str, const char *regex , int icas regerr = regexec(&re, str, re.re_nsub+1, subs, 0); if (regerr == REG_NOMATCH) { -#ifdef PHP_DEBUG +#ifdef PHP_DEBUG php_error_docref(NULL TSRMLS_CC, E_NOTICE, "'%s' does not match with '%s'", str, regex); #endif ret = FAILURE; @@ -5371,7 +5363,7 @@ static int php_pgsql_convert_match(const char *str, const char *regex , int icas static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) { smart_str str = {0}; - + assert(Z_TYPE_P(src) == IS_STRING); assert(should_free == 1 || should_free == 0); @@ -5380,7 +5372,7 @@ static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) smart_str_appendl(&str, Z_STRVAL_P(src), Z_STRLEN_P(src)); smart_str_appendc(&str, '\''); smart_str_0(&str); - + if (should_free) { efree(Z_STRVAL_P(src)); } @@ -5404,7 +5396,7 @@ static int php_pgsql_add_quotes(zval *src, zend_bool should_free TSRMLS_DC) php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Detected NULL for 'NOT NULL' field '%s'", field ); \ err = 1; \ } \ - } + } /* {{{ php_pgsql_convert * check and convert array values (fieldname=>vlaue pair) for sql @@ -5418,7 +5410,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con zval *meta, **def, **type, **not_null, **has_default, **is_enum, **val, *new_val; int key_type, err = 0, skip_field; php_pgsql_data_type data_type; - + assert(pg_link != NULL); assert(Z_TYPE_P(values) == IS_ARRAY); assert(Z_TYPE_P(result) == IS_ARRAY); @@ -5441,7 +5433,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos)) { skip_field = 0; new_val = NULL; - + if ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &field, &field_len, &num_idx, 0, &pos)) == HASH_KEY_NON_EXISTENT) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to get array key type"); err = 1; @@ -5522,7 +5514,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_LONG: case IS_BOOL: if (Z_LVAL_PP(val)) { @@ -5545,7 +5537,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects string, null, long or boolelan value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_OID: case PG_INT2: case PG_INT4: @@ -5557,7 +5549,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([+-]{0,1}[0-9]+)$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([+-]{0,1}[0-9]+)$", 0 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5565,7 +5557,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); convert_to_long_ex(&new_val); @@ -5599,7 +5591,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([+-]{0,1}[0-9]+)|([+-]{0,1}[0-9]*[\\.][0-9]+)|([+-]{0,1}[0-9]+[\\.][0-9]*)$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([+-]{0,1}[0-9]+)|([+-]{0,1}[0-9]*[\\.][0-9]+)|([+-]{0,1}[0-9]+[\\.][0-9]*)$", 0 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5607,15 +5599,15 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_LONG: ZVAL_LONG(new_val, Z_LVAL_PP(val)); break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5642,26 +5634,20 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } else { + char *tmp; Z_TYPE_P(new_val) = IS_STRING; -#if HAVE_PQESCAPE_CONN - { - char *tmp; - tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1); - Z_STRLEN_P(new_val) = (int)PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL); - Z_STRVAL_P(new_val) = tmp; - } -#else - Z_STRVAL_P(new_val) = (int)PQescapeString(Z_STRVAL_PP(val), Z_STRLEN_PP(val), &Z_STRLEN_P(new_val), 0 TSRMLS_CC); -#endif + tmp = (char *)safe_emalloc(Z_STRLEN_PP(val), 2, 1); + Z_STRLEN_P(new_val) = (int)PQescapeStringConn(pg_link, tmp, Z_STRVAL_PP(val), Z_STRLEN_PP(val), NULL); + Z_STRVAL_P(new_val) = tmp; php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); } break; - + case IS_LONG: ZVAL_LONG(new_val, Z_LVAL_PP(val)); convert_to_string_ex(&new_val); break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); convert_to_string_ex(&new_val); @@ -5679,7 +5665,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for PostgreSQL '%s' (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_UNIX_TIME: case PG_UNIX_TIME_INTERVAL: /* these are the actallay a integer */ @@ -5690,25 +5676,25 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: Better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^[0-9]+$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^[0-9]+$", 0 TSRMLS_CC) == FAILURE) { err = 1; - } + } else { ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); convert_to_long_ex(&new_val); } } break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); convert_to_long_ex(&new_val); break; - + case IS_LONG: ZVAL_LONG(new_val, Z_LVAL_PP(val)); break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5721,7 +5707,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL, string, long or double value for '%s' (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_CIDR: case PG_INET: switch (Z_TYPE_PP(val)) { @@ -5731,7 +5717,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: Better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/[0-9]{1,2}){0,1}$", 0 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{1,3}\\.){3}[0-9]{1,3}(/[0-9]{1,2}){0,1}$", 0 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5747,13 +5733,13 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con default: err = 1; - } + } PGSQL_CONV_CHECK_IGNORE(); if (err) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for '%s' (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_TIME_WITH_TIMEZONE: case PG_TIMESTAMP: case PG_TIMESTAMP_WITH_TIMEZONE: @@ -5765,7 +5751,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con ZVAL_STRINGL(new_val, "NOW()", sizeof("NOW()")-1, 1); } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}(\\.[0-9]+){0,1}([ \\t]*([+-][0-9]{1,4}(:[0-9]{1,2}){0,1}|[-a-zA-Z_/+]{1,50})){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})([ \\t]+(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1}(\\.[0-9]+){0,1}([ \\t]*([+-][0-9]{1,4}(:[0-9]{1,2}){0,1}|[-a-zA-Z_/+]{1,50})){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { err = 1; } else { ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); @@ -5773,7 +5759,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_NULL: ZVAL_STRINGL(new_val, "NULL", sizeof("NULL")-1, 1); break; @@ -5786,7 +5772,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects NULL or string for PostgreSQL %s field (%s)", Z_STRVAL_PP(type), field); } break; - + case PG_DATE: switch(Z_TYPE_PP(val)) { case IS_STRING: @@ -5795,7 +5781,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9]{4}[/-][0-9]{1,2}[/-][0-9]{1,2})$", 1 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5804,7 +5790,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5826,7 +5812,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } else { /* FIXME: better regex must be used */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^(([0-9]{1,2}:[0-9]{1,2}){1}(:[0-9]{1,2}){0,1})){0,1}$", 1 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5835,7 +5821,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5872,10 +5858,10 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con Quantities of days, hours, minutes, and seconds can be specified without explicit unit markings. For example, '1 12:59:10' is read the same as '1 day 12 hours 59 min 10 sec'. - */ - if (php_pgsql_convert_match(Z_STRVAL_PP(val), + */ + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^(@?[ \\t]+)?(" - + /* Textual time units and their abbreviations: */ "(([-+]?[ \\t]+)?" "[0-9]+(\\.[0-9]*)?[ \\t]*" @@ -5912,9 +5898,9 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con ZVAL_STRING(new_val, Z_STRVAL_PP(val), 1); php_pgsql_add_quotes(new_val, 1 TSRMLS_CC); } - } + } break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -5956,12 +5942,12 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con Z_STRLEN_P(new_val) = s.len; } break; - + case IS_LONG: ZVAL_LONG(new_val, Z_LVAL_PP(val)); convert_to_string_ex(&new_val); break; - + case IS_DOUBLE: ZVAL_DOUBLE(new_val, Z_DVAL_PP(val)); convert_to_string_ex(&new_val); @@ -5988,7 +5974,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con ZVAL_STRING(new_val, "NULL", 1); } else { - if (php_pgsql_convert_match(Z_STRVAL_PP(val), "^([0-9a-f]{2,2}:){5,5}[0-9a-f]{2,2}$", 1 TSRMLS_CC) == FAILURE) { + if (php_pgsql_convert_match(Z_STRVAL_PP(val), Z_STRLEN_PP(val), "^([0-9a-f]{2,2}:){5,5}[0-9a-f]{2,2}$", 1 TSRMLS_CC) == FAILURE) { err = 1; } else { @@ -5997,7 +5983,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con } } break; - + case IS_NULL: ZVAL_STRING(new_val, "NULL", 1); break; @@ -6032,7 +6018,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con err = 1; break; } /* switch */ - + if (err) { zval_dtor(new_val); FREE_ZVAL(new_val); @@ -6044,16 +6030,12 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con size_t field_len = strlen(field); if (_php_pgsql_detect_identifier_escape(field, field_len) == SUCCESS) { - escaped = _php_pgsql_strndup(field, field_len); + add_assoc_zval(result, field, new_val); } else { -#if HAVE_PQESCAPELITERAL - escaped = PQescapeIdentifier(pg_link, field, field_len); -#else - escaped = _php_pgsql_escape_identifier(field, field_len); -#endif + escaped = PGSQLescapeIdentifier(pg_link, field, field_len); + add_assoc_zval(result, escaped, new_val); + PGSQLfree(escaped); } - add_assoc_zval(result, escaped, new_val); - free(escaped); } } /* for */ zval_dtor(meta); @@ -6078,7 +6060,7 @@ PHP_FUNCTION(pg_convert) ulong option = 0; PGconn *pg_link; int id = -1; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa|l", &pgsql_link, &table_name, &table_name_len, &values, &option) == FAILURE) { return; @@ -6138,31 +6120,24 @@ static inline void build_tablename(smart_str *querystr, PGconn *pg_link, const c token = php_strtok_r(table_copy, ".", &tmp); len = strlen(token); if (_php_pgsql_detect_identifier_escape(token, len) == SUCCESS) { - escaped = _php_pgsql_strndup(token, len); + smart_str_appendl(querystr, token, len); } else { -#if HAVE_PQESCAPELITERAL - escaped = PQescapeIdentifier(pg_link, token, len); -#else - escaped = _php_pgsql_escape_identifier(token, len); -#endif + escaped = PGSQLescapeIdentifier(pg_link, token, len); + smart_str_appends(querystr, escaped); + PGSQLfree(escaped); } - smart_str_appends(querystr, escaped); - free(escaped); if (tmp && *tmp) { len = strlen(tmp); /* "schema"."table" format */ if (_php_pgsql_detect_identifier_escape(tmp, len) == SUCCESS) { - escaped = _php_pgsql_strndup(tmp, len); + smart_str_appendc(querystr, '.'); + smart_str_appendl(querystr, tmp, len); } else { -#if HAVE_PQESCAPELITERAL - escaped = PQescapeIdentifier(pg_link, tmp, len); -#else - escaped = _php_pgsql_escape_identifier(tmp, len); -#endif + escaped = PGSQLescapeIdentifier(pg_link, tmp, len); + smart_str_appendc(querystr, '.'); + smart_str_appends(querystr, escaped); + PGSQLfree(escaped); } - smart_str_appendc(querystr, '.'); - smart_str_appends(querystr, escaped); - free(escaped); } efree(table_copy); } @@ -6262,7 +6237,7 @@ no_values: cleanup: if (!(opt & PGSQL_DML_NO_CONV) && converted) { - zval_dtor(converted); + zval_dtor(converted); FREE_ZVAL(converted); } if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { @@ -6323,7 +6298,7 @@ static inline int build_assignment_string(smart_str *querystr, HashTable *ht, in for (zend_hash_internal_pointer_reset_ex(ht, &pos); zend_hash_get_current_data_ex(ht, (void **)&val, &pos) == SUCCESS; zend_hash_move_forward_ex(ht, &pos)) { - key_type = zend_hash_get_current_key_ex(ht, &fld, &fld_len, &num_idx, 0, &pos); + key_type = zend_hash_get_current_key_ex(ht, &fld, &fld_len, &num_idx, 0, &pos); if (key_type == HASH_KEY_IS_LONG) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects associative array for values to be inserted"); return -1; @@ -6334,7 +6309,7 @@ static inline int build_assignment_string(smart_str *querystr, HashTable *ht, in } else { smart_str_appendc(querystr, '='); } - + switch(Z_TYPE_PP(val)) { case IS_STRING: smart_str_appendl(querystr, Z_STRVAL_PP(val), Z_STRLEN_PP(val)); @@ -6463,7 +6438,7 @@ PHP_FUNCTION(pg_update) RETURN_STRING(sql, 0); } RETURN_TRUE; -} +} /* }}} */ /* {{{ php_pgsql_delete @@ -6510,7 +6485,7 @@ PHP_PGSQL_API int php_pgsql_delete(PGconn *pg_link, const char *table, zval *ids cleanup: if (!(opt & PGSQL_DML_NO_CONV)) { - zval_dtor(ids_converted); + zval_dtor(ids_converted); FREE_ZVAL(ids_converted); } if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { @@ -6614,7 +6589,7 @@ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids assert(Z_TYPE_P(ids_array) == IS_ARRAY); assert(Z_TYPE_P(ret_array) == IS_ARRAY); assert(!(opt & ~(PGSQL_CONV_OPTS|PGSQL_DML_NO_CONV|PGSQL_DML_EXEC|PGSQL_DML_ASYNC|PGSQL_DML_STRING))); - + if (zend_hash_num_elements(Z_ARRVAL_P(ids_array)) == 0) { return FAILURE; } @@ -6648,7 +6623,7 @@ PHP_PGSQL_API int php_pgsql_select(PGconn *pg_link, const char *table, zval *ids cleanup: if (!(opt & PGSQL_DML_NO_CONV)) { - zval_dtor(ids_converted); + zval_dtor(ids_converted); FREE_ZVAL(ids_converted); } if (ret == SUCCESS && (opt & PGSQL_DML_STRING)) { @@ -6696,7 +6671,7 @@ PHP_FUNCTION(pg_select) RETURN_STRING(sql, 0); } return; -} +} /* }}} */ #endif diff --git b/ext/pgsql/php_pgsql.h a/ext/pgsql/php_pgsql.h index 12d6cfd..d0853d6 100644 --- b/ext/pgsql/php_pgsql.h +++ a/ext/pgsql/php_pgsql.h @@ -16,7 +16,7 @@ | Jouni Ahto <jouni.ahto@exdec.fi> | +----------------------------------------------------------------------+ */ - + /* $Id$ */ #ifndef PHP_PGSQL_H diff --git b/main/php_version.h a/main/php_version.h index 784ef62..34f5128 100644 --- b/main/php_version.h +++ a/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 5 #define PHP_MINOR_VERSION 5 -#define PHP_RELEASE_VERSION 9 +#define PHP_RELEASE_VERSION 11 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "5.5.9-dev" -#define PHP_VERSION_ID 50509 +#define PHP_VERSION "5.5.11-dev" +#define PHP_VERSION_ID 50511