wez             Sat Sep 24 22:05:06 2005 EDT

  Modified files:              (Branch: PHP_5_1)
    /php-src/ext/pdo_mysql      mysql_statement.c 
  Log:
  Fixup LOB handling for inserts (refs #34630).
  
  Also tripped over the return of PECL #5200; looks like mysql doesn't return an
  accurate length for the columns.  The PDO driver will sanity check the real
  length against the buffer size it allocated (based on the info provided by
  mysql), so that we won't overrun the buffer.  In addition, if a varchar field
  is reported as having a length of less than 128, we'll allocate 128 just in
  case.
  
  If the data is truncated, report it via the appropriate sqlstate code.
  
  There must be a better way to do this stuff.
  
  
  
http://cvs.php.net/diff.php/php-src/ext/pdo_mysql/mysql_statement.c?r1=1.48.2.1&r2=1.48.2.2&ty=u
Index: php-src/ext/pdo_mysql/mysql_statement.c
diff -u php-src/ext/pdo_mysql/mysql_statement.c:1.48.2.1 
php-src/ext/pdo_mysql/mysql_statement.c:1.48.2.2
--- php-src/ext/pdo_mysql/mysql_statement.c:1.48.2.1    Wed Aug 31 21:57:01 2005
+++ php-src/ext/pdo_mysql/mysql_statement.c     Sat Sep 24 22:05:03 2005
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: mysql_statement.c,v 1.48.2.1 2005/09/01 01:57:01 iliaa Exp $ */
+/* $Id: mysql_statement.c,v 1.48.2.2 2005/09/25 02:05:03 wez Exp $ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -142,6 +142,26 @@
                                                                
S->fields[i].max_length? S->fields[i].max_length:
                                                                
S->fields[i].length;
                                        }
+#if 0
+                                       printf("%d: max_length=%d length=%d 
buffer_length=%d type=%d\n",
+                                                       i,
+                                                       S->fields[i].max_length,
+                                                       S->fields[i].length,
+                                                       
S->bound_result[i].buffer_length,
+                                                       S->fields[i].type
+                                                       );
+#endif
+
+                                       /* there are cases where the length 
reported by mysql is too short.
+                                        * eg: when describing a table that 
contains an enum column. Since
+                                        * we have no way of knowing the true 
length either, we'll bump up
+                                        * our buffer size to a reasonable 
size, just in case */
+                                       if (S->fields[i].max_length == 0 && 
S->bound_result[i].buffer_length < 128 && MYSQL_TYPE_VAR_STRING) {
+                                               
S->bound_result[i].buffer_length = 128;
+                                       }
+
+                                       S->out_length[i] = 0;
+
                                        S->bound_result[i].buffer = 
emalloc(S->bound_result[i].buffer_length);
                                        S->bound_result[i].is_null = 
&S->out_null[i];
                                        S->bound_result[i].length = 
&S->out_length[i];
@@ -291,9 +311,24 @@
                                }
        
                                switch (PDO_PARAM_TYPE(param->param_type)) {
-                                       case PDO_PARAM_LOB:
                                        case PDO_PARAM_STMT:
                                                return 0;
+                                       case PDO_PARAM_LOB:
+                                               if (Z_TYPE_P(param->parameter) 
== IS_RESOURCE) {
+                                                       php_stream *stm;
+                                                       
php_stream_from_zval_no_verify(stm, &param->parameter);
+                                                       if (stm) {
+                                                               
SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
+                                                               
Z_TYPE_P(param->parameter) = IS_STRING;
+                                                               
Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
+                                                                       
&Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
+                                                       } else {
+                                                               
pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
+                                                               return 0;
+                                                       }
+                                               }
+                                               /* fall through */
+
                                        default:
                                                ;
                                }
@@ -423,6 +458,13 @@
                        return 1;
                }
                *ptr = S->bound_result[colno].buffer;
+               if (S->out_length[colno] > 
S->bound_result[colno].buffer_length) {
+                       /* mysql lied about the column width */
+                       strcpy(stmt->error_code, "01004"); /* truncated */
+                       S->out_length[colno] = 
S->bound_result[colno].buffer_length;
+                       *len = S->out_length[colno];
+                       return 0;
+               }
                *len = S->out_length[colno];
                return 1;
        }

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to