コード例 #1
0
ファイル: IPC.c プロジェクト: dreamsxin/php-ion
/** public function ION\Process\IPC::getContext() : mixed */
CLASS_METHOD(ION_Process_IPC, getContext) {
    ion_process_ipc * ipc = ION_THIS_OBJECT(ion_process_ipc);
    if(!Z_ISUNDEF(ipc->ctx)) {
        if(!Z_ISREF(ipc->ctx)) {
            zval ref;
            ZVAL_NEW_EMPTY_REF(&ref);
            ZVAL_COPY_VALUE(Z_REFVAL(ref), &ipc->ctx);
            ZVAL_COPY_VALUE(return_value, &ref);
        } else {
            ZVAL_COPY(return_value, &ipc->ctx);
        }
    }
}
コード例 #2
0
ファイル: oci_statement.c プロジェクト: dzuelke/php-src
static sb4 oci_bind_output_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodepp) /* {{{ */
{
	struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx;
	pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data;
	zval *parameter;

	if (!param) {
		php_error_docref(NULL, E_WARNING, "param is NULL in oci_bind_output_cb; this should not happen");
		return OCI_ERROR;
	}

	if (Z_ISREF(param->parameter))
        parameter = Z_REFVAL(param->parameter);
    else
        parameter = &param->parameter;

	if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
		P->actual_len = sizeof(OCILobLocator*);
		*bufpp = P->thing;
		*alenpp = &P->actual_len;
		*piecep = OCI_ONE_PIECE;
		*rcodepp = &P->retcode;
		*indpp = &P->indicator;
		return OCI_CONTINUE;
	}

	if (Z_TYPE_P(parameter) == IS_OBJECT || Z_TYPE_P(parameter) == IS_RESOURCE) {
		return OCI_CONTINUE;
	}

	convert_to_string(parameter);
	zval_dtor(parameter);

	Z_STR_P(parameter) = zend_string_alloc(param->max_value_len, 1);
	P->used_for_output = 1;

	P->actual_len = (ub4) Z_STRLEN_P(parameter);
	*alenpp = &P->actual_len;
	*bufpp = (Z_STR_P(parameter))->val;
	*piecep = OCI_ONE_PIECE;
	*rcodepp = &P->retcode;
	*indpp = &P->indicator;

	return OCI_CONTINUE;
} /* }}} */
コード例 #3
0
ファイル: oci_statement.c プロジェクト: dzuelke/php-src
static sb4 oci_bind_input_cb(dvoid *ctx, OCIBind *bindp, ub4 iter, ub4 index, dvoid **bufpp, ub4 *alenp, ub1 *piecep, dvoid **indpp) /* {{{ */
{
	struct pdo_bound_param_data *param = (struct pdo_bound_param_data*)ctx;
	pdo_oci_bound_param *P = (pdo_oci_bound_param*)param->driver_data;
	zval *parameter;

	if (!param) {
		php_error_docref(NULL, E_WARNING, "param is NULL in oci_bind_input_cb; this should not happen");
		return OCI_ERROR;
	}

	*indpp = &P->indicator;

    if (Z_ISREF(param->parameter))
		parameter = Z_REFVAL(param->parameter);
	else
		parameter = &param->parameter;

	if (P->thing) {
		*bufpp = P->thing;
		*alenp = sizeof(void*);
	} else if (ZVAL_IS_NULL(parameter)) {
		/* insert a NULL value into the column */
		P->indicator = -1; /* NULL */
		*bufpp = 0;
		*alenp = -1;
	} else if (!P->thing) {
		/* regular string bind */
		convert_to_string(parameter);
		*bufpp = Z_STRVAL_P(parameter);
		*alenp = (ub4) Z_STRLEN_P(parameter);
	}

	*piecep = OCI_ONE_PIECE;
	return OCI_CONTINUE;
} /* }}} */
コード例 #4
0
ファイル: scanf.c プロジェクト: 13572293130/php-src
PHPAPI int php_sscanf_internal( char *string, char *format,
				int argCount, zval *args,
				int varStart, zval *return_value)
{
	int  numVars, nconversions, totalVars = -1;
	int  i, result;
	zend_long value;
	int  objIndex;
	char *end, *baseString;
	zval *current;
	char op   = 0;
	int  base = 0;
	int  underflow = 0;
	size_t width;
	zend_long (*fn)() = NULL;
	char *ch, sch;
	int  flags;
	char buf[64];	/* Temporary buffer to hold scanned number
					 * strings before they are passed to strtoul() */

	/* do some sanity checking */
	if ((varStart > argCount) || (varStart < 0)){
		varStart = SCAN_MAX_ARGS + 1;
	}
	numVars = argCount - varStart;
	if (numVars < 0) {
		numVars = 0;
	}

#if 0
	zend_printf("<br>in sscanf_internal : <br> string is \"%s\", format = \"%s\"<br> NumVars = %d. VarStart = %d<br>-------------------------<br>",
					string, format, numVars, varStart);
#endif
	/*
	 * Check for errors in the format string.
	 */
	if (ValidateFormat(format, numVars, &totalVars) != SCAN_SUCCESS) {
		scan_set_error_return( numVars, return_value );
		return SCAN_ERROR_INVALID_FORMAT;
	}

	objIndex = numVars ? varStart : 0;

	/*
	 * If any variables are passed, make sure they are all passed by reference
	 */
	if (numVars) {
		for (i = varStart;i < argCount;i++){
			if ( ! Z_ISREF(args[ i ] ) ) {
				php_error_docref(NULL, E_WARNING, "Parameter %d must be passed by reference", i);
				scan_set_error_return(numVars, return_value);
				return SCAN_ERROR_VAR_PASSED_BYVAL;
			}
		}
	}

	/*
	 * Allocate space for the result objects. Only happens when no variables
	 * are specified
	 */
	if (!numVars) {
		zval tmp;

		/* allocate an array for return */
		array_init(return_value);

		for (i = 0; i < totalVars; i++) {
			ZVAL_NULL(&tmp);
			if (add_next_index_zval(return_value, &tmp) == FAILURE) {
				scan_set_error_return(0, return_value);
				return FAILURE;
			}
		}
		varStart = 0; /* Array index starts from 0 */
	}

	baseString = string;

	/*
	 * Iterate over the format string filling in the result objects until
	 * we reach the end of input, the end of the format string, or there
	 * is a mismatch.
	 */
	nconversions = 0;
	/* note ! - we need to limit the loop for objIndex to keep it in bounds */

	while (*format != '\0') {
		ch    = format++;
		flags = 0;

		/*
		 * If we see whitespace in the format, skip whitespace in the string.
		 */
		if ( isspace( (int)*ch ) ) {
			sch = *string;
			while ( isspace( (int)sch ) ) {
				if (*string == '\0') {
					goto done;
				}
				string++;
				sch = *string;
			}
			continue;
		}

		if (*ch != '%') {
literal:
			if (*string == '\0') {
				underflow = 1;
				goto done;
			}
			sch = *string;
			string++;
			if (*ch != sch) {
				goto done;
			}
			continue;
		}

		ch = format++;
		if (*ch == '%') {
			goto literal;
		}

		/*
		 * Check for assignment suppression ('*') or an XPG3-style
		 * assignment ('%n$').
		 */
		if (*ch == '*') {
			flags |= SCAN_SUPPRESS;
			ch = format++;
		} else if ( isdigit(UCHAR(*ch))) {
			value = ZEND_STRTOUL(format-1, &end, 10);
			if (*end == '$') {
				format = end+1;
				ch = format++;
				objIndex = varStart + value - 1;
			}
		}

		/*
		 * Parse any width specifier.
		 */
		if ( isdigit(UCHAR(*ch))) {
			width = ZEND_STRTOUL(format-1, &format, 10);
			ch = format++;
		} else {
			width = 0;
		}

		/*
		 * Ignore size specifier.
		 */
		if ((*ch == 'l') || (*ch == 'L') || (*ch == 'h')) {
			ch = format++;
		}

		/*
		 * Handle the various field types.
		 */
		switch (*ch) {
			case 'n':
				if (!(flags & SCAN_SUPPRESS)) {
					if (numVars && objIndex >= argCount) {
						break;
					} else if (numVars) {
						current = Z_REFVAL(args[objIndex++]);
						zval_ptr_dtor(current);
						ZVAL_LONG(current, (zend_long)(string - baseString) );
					} else {
						add_index_long(return_value, objIndex++, string - baseString);
					}
				}
				nconversions++;
				continue;

			case 'd':
			case 'D':
				op = 'i';
				base = 10;
				fn = (zend_long (*)())ZEND_STRTOL_PTR;
				break;
			case 'i':
				op = 'i';
				base = 0;
				fn = (zend_long (*)())ZEND_STRTOL_PTR;
				break;
			case 'o':
				op = 'i';
				base = 8;
				fn = (zend_long (*)())ZEND_STRTOL_PTR;
				break;
			case 'x':
			case 'X':
				op = 'i';
				base = 16;
				fn = (zend_long (*)())ZEND_STRTOL_PTR;
				break;
			case 'u':
				op = 'i';
				base = 10;
				flags |= SCAN_UNSIGNED;
				fn = (zend_long (*)())ZEND_STRTOUL_PTR;
				break;

			case 'f':
			case 'e':
			case 'E':
			case 'g':
				op = 'f';
				break;

			case 's':
				op = 's';
				break;

			case 'c':
				op = 's';
				flags |= SCAN_NOSKIP;
				/*-cc-*/
				if (0 == width) {
					width = 1;
				}
				/*-cc-*/
				break;
			case '[':
				op = '[';
				flags |= SCAN_NOSKIP;
				break;
		}   /* switch */

		/*
		 * At this point, we will need additional characters from the
		 * string to proceed.
		 */
		if (*string == '\0') {
			underflow = 1;
			goto done;
		}

		/*
		 * Skip any leading whitespace at the beginning of a field unless
		 * the format suppresses this behavior.
		 */
		if (!(flags & SCAN_NOSKIP)) {
			while (*string != '\0') {
				sch = *string;
				if (! isspace((int)sch) ) {
					break;
				}
				string++;
			}
			if (*string == '\0') {
				underflow = 1;
				goto done;
			}
		}

		/*
		 * Perform the requested scanning operation.
		 */
		switch (op) {
			case 'c':
			case 's':
				/*
				 * Scan a string up to width characters or whitespace.
				 */
				if (width == 0) {
					width = (size_t) ~0;
				}
				end = string;
				while (*end != '\0') {
					sch = *end;
					if ( isspace( (int)sch ) ) {
						break;
					}
					end++;
					if (--width == 0) {
					   break;
					}
				}
				if (!(flags & SCAN_SUPPRESS)) {
					if (numVars && objIndex >= argCount) {
						break;
					} else if (numVars) {
						current = Z_REFVAL(args[objIndex++]);
						zval_ptr_dtor(current);
						ZVAL_STRINGL(current, string, end-string);
					} else {
						add_index_stringl(return_value, objIndex++, string, end-string);
					}
				}
				string = end;
				break;

			case '[': {
				CharSet cset;

				if (width == 0) {
					width = (size_t) ~0;
				}
				end = string;

				format = BuildCharSet(&cset, format);
				while (*end != '\0') {
					sch = *end;
					if (!CharInSet(&cset, (int)sch)) {
						break;
					}
					end++;
					if (--width == 0) {
						break;
					}
				}
				ReleaseCharSet(&cset);

				if (string == end) {
					/*
					 * Nothing matched the range, stop processing
					 */
					goto done;
				}
				if (!(flags & SCAN_SUPPRESS)) {
					if (numVars && objIndex >= argCount) {
						break;
					} else if (numVars) {
						current = Z_REFVAL(args[objIndex++]);
						zval_ptr_dtor(current);
						ZVAL_STRINGL(current, string, end-string);
					} else {
						add_index_stringl(return_value, objIndex++, string, end-string);
					}
				}
				string = end;
				break;
			}
/*
			case 'c':
			   / Scan a single character./

				sch = *string;
				string++;
				if (!(flags & SCAN_SUPPRESS)) {
					if (numVars) {
						char __buf[2];
						__buf[0] = sch;
						__buf[1] = '\0';;
						current = args[objIndex++];
						zval_dtor(*current);
						ZVAL_STRINGL( *current, __buf, 1);
					} else {
						add_index_stringl(return_value, objIndex++, &sch, 1);
					}
				}
				break;
*/
			case 'i':
				/*
				 * Scan an unsigned or signed integer.
				 */
				/*-cc-*/
				buf[0] = '\0';
				/*-cc-*/
				if ((width == 0) || (width > sizeof(buf) - 1)) {
					width = sizeof(buf) - 1;
				}

				flags |= SCAN_SIGNOK | SCAN_NODIGITS | SCAN_NOZERO;
				for (end = buf; width > 0; width--) {
					switch (*string) {
						/*
						 * The 0 digit has special meaning at the beginning of
						 * a number.  If we are unsure of the base, it
						 * indicates that we are in base 8 or base 16 (if it is
						 * followed by an 'x').
						 */
						case '0':
							/*-cc-*/
							if (base == 16) {
								flags |= SCAN_XOK;
							}
							/*-cc-*/
							if (base == 0) {
								base = 8;
								flags |= SCAN_XOK;
							}
							if (flags & SCAN_NOZERO) {
								flags &= ~(SCAN_SIGNOK | SCAN_NODIGITS | SCAN_NOZERO);
							} else {
								flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
							}
							goto addToInt;

						case '1': case '2': case '3': case '4':
						case '5': case '6': case '7':
							if (base == 0) {
								base = 10;
							}
							flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
							goto addToInt;

						case '8': case '9':
							if (base == 0) {
								base = 10;
							}
							if (base <= 8) {
							   break;
							}
							flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
							goto addToInt;

						case 'A': case 'B': case 'C':
						case 'D': case 'E': case 'F':
						case 'a': case 'b': case 'c':
						case 'd': case 'e': case 'f':
							if (base <= 10) {
								break;
							}
							flags &= ~(SCAN_SIGNOK | SCAN_XOK | SCAN_NODIGITS);
							goto addToInt;

						case '+': case '-':
							if (flags & SCAN_SIGNOK) {
								flags &= ~SCAN_SIGNOK;
								goto addToInt;
							}
							break;

						case 'x': case 'X':
							if ((flags & SCAN_XOK) && (end == buf+1)) {
								base = 16;
								flags &= ~SCAN_XOK;
								goto addToInt;
							}
							break;
					}

					/*
					 * We got an illegal character so we are done accumulating.
					 */
					break;

addToInt:
					/*
					 * Add the character to the temporary buffer.
					 */
					*end++ = *string++;
					if (*string == '\0') {
						break;
					}
				}

				/*
				 * Check to see if we need to back up because we only got a
				 * sign or a trailing x after a 0.
				 */
				if (flags & SCAN_NODIGITS) {
					if (*string == '\0') {
						underflow = 1;
					}
					goto done;
				} else if (end[-1] == 'x' || end[-1] == 'X') {
					end--;
					string--;
				}

				/*
				 * Scan the value from the temporary buffer.  If we are
				 * returning a large unsigned value, we have to convert it back
				 * to a string since PHP only supports signed values.
				 */
				if (!(flags & SCAN_SUPPRESS)) {
					*end = '\0';
					value = (zend_long) (*fn)(buf, NULL, base);
					if ((flags & SCAN_UNSIGNED) && (value < 0)) {
						snprintf(buf, sizeof(buf), ZEND_ULONG_FMT, value); /* INTL: ISO digit */
						if (numVars && objIndex >= argCount) {
							break;
						} else if (numVars) {
						  /* change passed value type to string */
							current = Z_REFVAL(args[objIndex++]);
							zval_ptr_dtor(current);
							ZVAL_STRING(current, buf);
						} else {
							add_index_string(return_value, objIndex++, buf);
						}
					} else {
						if (numVars && objIndex >= argCount) {
							break;
						} else if (numVars) {
							current = Z_REFVAL(args[objIndex++]);
							zval_ptr_dtor(current);
							ZVAL_LONG(current, value);
						} else {
							add_index_long(return_value, objIndex++, value);
						}
					}
				}
				break;

			case 'f':
				/*
				 * Scan a floating point number
				 */
				buf[0] = '\0';     /* call me pedantic */
				if ((width == 0) || (width > sizeof(buf) - 1)) {
					width = sizeof(buf) - 1;
				}
				flags |= SCAN_SIGNOK | SCAN_NODIGITS | SCAN_PTOK | SCAN_EXPOK;
				for (end = buf; width > 0; width--) {
					switch (*string) {
						case '0': case '1': case '2': case '3':
						case '4': case '5': case '6': case '7':
						case '8': case '9':
							flags &= ~(SCAN_SIGNOK | SCAN_NODIGITS);
							goto addToFloat;
						case '+':
						case '-':
							if (flags & SCAN_SIGNOK) {
								flags &= ~SCAN_SIGNOK;
								goto addToFloat;
							}
							break;
						case '.':
							if (flags & SCAN_PTOK) {
								flags &= ~(SCAN_SIGNOK | SCAN_PTOK);
								goto addToFloat;
							}
							break;
						case 'e':
						case 'E':
							/*
							 * An exponent is not allowed until there has
							 * been at least one digit.
							 */
							if ((flags & (SCAN_NODIGITS | SCAN_EXPOK)) == SCAN_EXPOK) {
								flags = (flags & ~(SCAN_EXPOK|SCAN_PTOK))
									| SCAN_SIGNOK | SCAN_NODIGITS;
								goto addToFloat;
							}
							break;
					}

					/*
					 * We got an illegal character so we are done accumulating.
					 */
					break;

addToFloat:
					/*
					 * Add the character to the temporary buffer.
					 */
					*end++ = *string++;
					if (*string == '\0') {
						break;
					}
				}

				/*
				 * Check to see if we need to back up because we saw a
				 * trailing 'e' or sign.
				 */
				if (flags & SCAN_NODIGITS) {
					if (flags & SCAN_EXPOK) {
						/*
						 * There were no digits at all so scanning has
						 * failed and we are done.
						 */
						if (*string == '\0') {
							underflow = 1;
						}
						goto done;
					}

					/*
					 * We got a bad exponent ('e' and maybe a sign).
					 */
					end--;
					string--;
					if (*end != 'e' && *end != 'E') {
						end--;
						string--;
					}
				}

				/*
				 * Scan the value from the temporary buffer.
				 */
				if (!(flags & SCAN_SUPPRESS)) {
					double dvalue;
					*end = '\0';
					dvalue = zend_strtod(buf, NULL);
					if (numVars && objIndex >= argCount) {
						break;
					} else if (numVars) {
						current = Z_REFVAL(args[objIndex++]);
						zval_ptr_dtor(current);
						ZVAL_DOUBLE(current, dvalue);
					} else {
						add_index_double(return_value, objIndex++, dvalue );
					}
				}
				break;
		} /* switch (op) */
		nconversions++;
	} /*  while (*format != '\0') */

done:
	result = SCAN_SUCCESS;

	if (underflow && (0==nconversions)) {
		scan_set_error_return( numVars, return_value );
		result = SCAN_ERROR_EOF;
	} else if (numVars) {
		convert_to_long(return_value );
		Z_LVAL_P(return_value) = nconversions;
	} else if (nconversions < totalVars) {
		/* TODO: not all elements converted. we need to prune the list - cc */
	}
	return result;
}
コード例 #5
0
ファイル: pdo_sql_parser.c プロジェクト: 13572293130/php-src
PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, size_t inquery_len,
	char **outquery, size_t *outquery_len)
{
	Scanner s;
	char *ptr, *newbuffer;
	int t;
	int bindno = 0;
	int ret = 0;
	size_t newbuffer_len;
	HashTable *params;
	struct pdo_bound_param_data *param;
	int query_type = PDO_PLACEHOLDER_NONE;
	struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;

	ptr = *outquery;
	s.cur = inquery;
	s.end = inquery + inquery_len + 1;

	/* phase 1: look for args */
	while((t = scan(&s)) != PDO_PARSER_EOI) {
		if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
			if (t == PDO_PARSER_BIND) {
				int len = s.cur - s.tok;
				if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) {
					continue;
				}
				query_type |= PDO_PLACEHOLDER_NAMED;
			} else {
				query_type |= PDO_PLACEHOLDER_POSITIONAL;
			}

			plc = emalloc(sizeof(*plc));
			memset(plc, 0, sizeof(*plc));
			plc->next = NULL;
			plc->pos = s.tok;
			plc->len = s.cur - s.tok;
			plc->bindno = bindno++;

			if (placetail) {
				placetail->next = plc;
			} else {
				placeholders = plc;
			}
			placetail = plc;
		}
	}

	if (bindno == 0) {
		/* nothing to do; good! */
		return 0;
	}

	/* did the query make sense to me? */
	if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
		/* they mixed both types; punt */
		pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters");
		ret = -1;
		goto clean_up;
	}

	if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
		/* query matches native syntax */
		ret = 0;
		goto clean_up;
	}

	if (stmt->named_rewrite_template) {
		/* magic/hack.
		 * We we pretend that the query was positional even if
		 * it was named so that we fall into the
		 * named rewrite case below.  Not too pretty,
		 * but it works. */
		query_type = PDO_PLACEHOLDER_POSITIONAL;
	}

	params = stmt->bound_params;

	/* Do we have placeholders but no bound params */
	if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
		pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound");
		ret = -1;
		goto clean_up;
	}

	if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
		/* extra bit of validation for instances when same params are bound more than once */
		if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
			int ok = 1;
			for (plc = placeholders; plc; plc = plc->next) {
				if ((param = zend_hash_str_find_ptr(params, plc->pos, plc->len)) == NULL) {
					ok = 0;
					break;
				}
			}
			if (ok) {
				goto safe;
			}
		}
		pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens");
		ret = -1;
		goto clean_up;
	}
safe:
	/* what are we going to do ? */
	if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
		/* query generation */

		newbuffer_len = inquery_len;

		/* let's quote all the values */
		for (plc = placeholders; plc; plc = plc->next) {
			if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
				param = zend_hash_index_find_ptr(params, plc->bindno);
			} else {
				param = zend_hash_str_find_ptr(params, plc->pos, plc->len);
			}
			if (param == NULL) {
				/* parameter was not defined */
				ret = -1;
				pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined");
				goto clean_up;
			}
			if (stmt->dbh->methods->quoter) {
				zval *parameter;
				if (Z_ISREF(param->parameter)) {
					parameter = Z_REFVAL(param->parameter);
				} else {
					parameter = &param->parameter;
				}
				if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(parameter) == IS_RESOURCE) {
					php_stream *stm;

					php_stream_from_zval_no_verify(stm, parameter);
					if (stm) {
						zend_string *buf;

						buf = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
						if (!buf) {
							buf = ZSTR_EMPTY_ALLOC();
						}
						if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), ZSTR_LEN(buf), &plc->quoted, &plc->qlen,
								param->param_type)) {
							/* bork */
							ret = -1;
							strncpy(stmt->error_code, stmt->dbh->error_code, 6);
							if (buf) {
								zend_string_release(buf);
							}
							goto clean_up;
						}
						if (buf) {
							zend_string_release(buf);
						}
					} else {
						pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
						ret = -1;
						goto clean_up;
					}
					plc->freeq = 1;
				} else {
					zval tmp_param;
				   	ZVAL_DUP(&tmp_param, parameter);
					switch (Z_TYPE(tmp_param)) {
						case IS_NULL:
							plc->quoted = "NULL";
							plc->qlen = sizeof("NULL")-1;
							plc->freeq = 0;
							break;

						case IS_FALSE:
						case IS_TRUE:
							convert_to_long(&tmp_param);
							/* fall through */
						case IS_LONG:
						case IS_DOUBLE:
							convert_to_string(&tmp_param);
							plc->qlen = Z_STRLEN(tmp_param);
							plc->quoted = estrdup(Z_STRVAL(tmp_param));
							plc->freeq = 1;
							break;

						default:
							convert_to_string(&tmp_param);
							if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL(tmp_param),
									Z_STRLEN(tmp_param), &plc->quoted, &plc->qlen,
									param->param_type)) {
								/* bork */
								ret = -1;
								strncpy(stmt->error_code, stmt->dbh->error_code, 6);
								goto clean_up;
							}
							plc->freeq = 1;
					}
					zval_dtor(&tmp_param);
				}
			} else {
				zval *parameter;
				if (Z_ISREF(param->parameter)) {
					parameter = Z_REFVAL(param->parameter);
				} else {
					parameter = &param->parameter;
				}
				plc->quoted = Z_STRVAL_P(parameter);
				plc->qlen = Z_STRLEN_P(parameter);
			}
			newbuffer_len += plc->qlen;
		}

rewrite:
		/* allocate output buffer */
		newbuffer = emalloc(newbuffer_len + 1);
		*outquery = newbuffer;

		/* and build the query */
		plc = placeholders;
		ptr = inquery;

		do {
			t = plc->pos - ptr;
			if (t) {
				memcpy(newbuffer, ptr, t);
				newbuffer += t;
			}
			memcpy(newbuffer, plc->quoted, plc->qlen);
			newbuffer += plc->qlen;
			ptr = plc->pos + plc->len;

			plc = plc->next;
		} while (plc);

		t = (inquery + inquery_len) - ptr;
		if (t) {
			memcpy(newbuffer, ptr, t);
			newbuffer += t;
		}
		*newbuffer = '\0';
		*outquery_len = newbuffer - *outquery;

		ret = 1;
		goto clean_up;

	} else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
		/* rewrite ? to :pdoX */
		char *name, *idxbuf;
		const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d";
		int bind_no = 1;

		newbuffer_len = inquery_len;

		if (stmt->bound_param_map == NULL) {
			ALLOC_HASHTABLE(stmt->bound_param_map);
			zend_hash_init(stmt->bound_param_map, 13, NULL, free_param_name, 0);
		}

		for (plc = placeholders; plc; plc = plc->next) {
			int skip_map = 0;
			char *p;
			name = estrndup(plc->pos, plc->len);

			/* check if bound parameter is already available */
			if (!strcmp(name, "?") || (p = zend_hash_str_find_ptr(stmt->bound_param_map, name, plc->len)) == NULL) {
				spprintf(&idxbuf, 0, tmpl, bind_no++);
			} else {
				idxbuf = estrdup(p);
				skip_map = 1;
			}

			plc->quoted = idxbuf;
			plc->qlen = strlen(plc->quoted);
			plc->freeq = 1;
			newbuffer_len += plc->qlen;

			if (!skip_map && stmt->named_rewrite_template) {
				/* create a mapping */
				zend_hash_str_update_mem(stmt->bound_param_map, name, plc->len, idxbuf, plc->qlen + 1);
			}

			/* map number to name */
			zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1);

			efree(name);
		}

		goto rewrite;

	} else {
		/* rewrite :name to ? */

		newbuffer_len = inquery_len;

		if (stmt->bound_param_map == NULL) {
			ALLOC_HASHTABLE(stmt->bound_param_map);
			zend_hash_init(stmt->bound_param_map, 13, NULL, free_param_name, 0);
		}

		for (plc = placeholders; plc; plc = plc->next) {
			char *name;
			name = estrndup(plc->pos, plc->len);
			zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, name, plc->len + 1);
			efree(name);
			plc->quoted = "?";
			plc->qlen = 1;
		}

		goto rewrite;
	}

clean_up:

	while (placeholders) {
		plc = placeholders;
		placeholders = plc->next;

		if (plc->freeq) {
			efree(plc->quoted);
		}

		efree(plc);
	}

	return ret;
}
コード例 #6
0
static int pdo_sqlite_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
		enum pdo_param_event event_type)
{
	pdo_sqlite_stmt *S = (pdo_sqlite_stmt*)stmt->driver_data;
	zval *parameter;

	switch (event_type) {
		case PDO_PARAM_EVT_EXEC_PRE:
			if (stmt->executed && !S->done) {
				sqlite3_reset(S->stmt);
				S->done = 1;
			}

			if (param->is_param) {

				if (param->paramno == -1) {
					param->paramno = sqlite3_bind_parameter_index(S->stmt, ZSTR_VAL(param->name)) - 1;
				}

				switch (PDO_PARAM_TYPE(param->param_type)) {
					case PDO_PARAM_STMT:
						return 0;

					case PDO_PARAM_NULL:
						if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
							return 1;
						}
						pdo_sqlite_error_stmt(stmt);
						return 0;

					case PDO_PARAM_INT:
					case PDO_PARAM_BOOL:
						if (Z_ISREF(param->parameter)) {
							parameter = Z_REFVAL(param->parameter);
						} else {
							parameter = &param->parameter;
						}
						if (Z_TYPE_P(parameter) == IS_NULL) {
							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
								return 1;
							}
						} else {
							convert_to_long(parameter);
#if ZEND_LONG_MAX > 2147483647
							if (SQLITE_OK == sqlite3_bind_int64(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
								return 1;
							}
#else
							if (SQLITE_OK == sqlite3_bind_int(S->stmt, param->paramno + 1, Z_LVAL_P(parameter))) {
								return 1;
							}
#endif
						}
						pdo_sqlite_error_stmt(stmt);
						return 0;

					case PDO_PARAM_LOB:
						if (Z_ISREF(param->parameter)) {
							parameter = Z_REFVAL(param->parameter);
						} else {
							parameter = &param->parameter;
						}
						if (Z_TYPE_P(parameter) == IS_RESOURCE) {
							php_stream *stm = NULL;
							php_stream_from_zval_no_verify(stm, parameter);
							if (stm) {
								zend_string *mem = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
								zval_ptr_dtor(parameter);
								ZVAL_STR(parameter, mem ? mem : ZSTR_EMPTY_ALLOC());
							} else {
								pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource");
								return 0;
							}
						} else if (Z_TYPE_P(parameter) == IS_NULL) {
							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
								return 1;
							}
							pdo_sqlite_error_stmt(stmt);
							return 0;
						} else {
							convert_to_string(parameter);
						}

						if (SQLITE_OK == sqlite3_bind_blob(S->stmt, param->paramno + 1,
								Z_STRVAL_P(parameter),
								Z_STRLEN_P(parameter),
								SQLITE_STATIC)) {
							return 1;
						}
						return 0;

					case PDO_PARAM_STR:
					default:
						if (Z_ISREF(param->parameter)) {
							parameter = Z_REFVAL(param->parameter);
						} else {
							parameter = &param->parameter;
						}
						if (Z_TYPE_P(parameter) == IS_NULL) {
							if (sqlite3_bind_null(S->stmt, param->paramno + 1) == SQLITE_OK) {
								return 1;
							}
						} else {
							convert_to_string(parameter);
							if (SQLITE_OK == sqlite3_bind_text(S->stmt, param->paramno + 1,
									Z_STRVAL_P(parameter),
									Z_STRLEN_P(parameter),
									SQLITE_STATIC)) {
								return 1;
							}
						}
						pdo_sqlite_error_stmt(stmt);
						return 0;
				}
			}
			break;

		default:
			;
	}
	return 1;
}
コード例 #7
0
ファイル: pgsql_statement.c プロジェクト: 0xhacking/php-src
static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
		enum pdo_param_event event_type)
{
	pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;

	if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED && param->is_param) {
		switch (event_type) {
			case PDO_PARAM_EVT_FREE:
				if (param->driver_data) {
					efree(param->driver_data);
				}
				break;

			case PDO_PARAM_EVT_NORMALIZE:
				/* decode name from $1, $2 into 0, 1 etc. */
				if (param->name) {
					if (param->name->val[0] == '$') {
						ZEND_ATOL(param->paramno, param->name->val + 1);
					} else {
						/* resolve parameter name to rewritten name */
						char *namevar;

						if (stmt->bound_param_map && (namevar = zend_hash_find_ptr(stmt->bound_param_map,
								param->name)) != NULL) {
							ZEND_ATOL(param->paramno, namevar + 1);
							param->paramno--;
						} else {
							pdo_raise_impl_error(stmt->dbh, stmt, "HY093", param->name->val);
							return 0;
						}
					}
				}
				break;

			case PDO_PARAM_EVT_ALLOC:
			case PDO_PARAM_EVT_EXEC_POST:
			case PDO_PARAM_EVT_FETCH_PRE:
			case PDO_PARAM_EVT_FETCH_POST:
				/* work is handled by EVT_NORMALIZE */
				return 1;

			case PDO_PARAM_EVT_EXEC_PRE:
				if (!stmt->bound_param_map) {
					return 0;
				}
				if (!S->param_values) {
					S->param_values = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(char*));
					S->param_lengths = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(int));
					S->param_formats = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(int));
					S->param_types = ecalloc(
							zend_hash_num_elements(stmt->bound_param_map),
							sizeof(Oid));
				}
				if (param->paramno >= 0) {
					zval *parameter;

					if (param->paramno >= zend_hash_num_elements(stmt->bound_params)) {
						pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined");
						return 0;
					}

					if (Z_ISREF(param->parameter)) {
						parameter = Z_REFVAL(param->parameter);
					} else {
						parameter = &param->parameter;
					}

					if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB &&
							Z_TYPE_P(parameter) == IS_RESOURCE) {
						php_stream *stm;
						php_stream_from_zval_no_verify(stm, parameter);
						if (stm) {
							if (php_stream_is(stm, &pdo_pgsql_lob_stream_ops)) {
								struct pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract;
								pdo_pgsql_bound_param *P = param->driver_data;

								if (P == NULL) {
									P = ecalloc(1, sizeof(*P));
									param->driver_data = P;
								}
								P->oid = htonl(self->oid);
								S->param_values[param->paramno] = (char*)&P->oid;
								S->param_lengths[param->paramno] = sizeof(P->oid);
								S->param_formats[param->paramno] = 1;
								S->param_types[param->paramno] = OIDOID;
								return 1;
							} else {
								zend_string *str = php_stream_copy_to_mem(stm, PHP_STREAM_COPY_ALL, 0);
								if (str != NULL) {
									//??SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
									ZVAL_STR(parameter, str);
								} else {
									ZVAL_EMPTY_STRING(parameter);
								}
							}
						} else {
							/* expected a stream resource */
							pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
							return 0;
						}
					}

					if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL ||
							Z_TYPE_P(parameter) == IS_NULL) {
						S->param_values[param->paramno] = NULL;
						S->param_lengths[param->paramno] = 0;
					} else if (Z_TYPE_P(parameter) == IS_FALSE || Z_TYPE_P(parameter) == IS_TRUE) {
						S->param_values[param->paramno] = Z_TYPE_P(parameter) == IS_TRUE ? "t" : "f";
						S->param_lengths[param->paramno] = 1;
						S->param_formats[param->paramno] = 0;
					} else {
						//SEPARATE_ZVAL_IF_NOT_REF(&param->parameter);
						convert_to_string_ex(parameter);
						S->param_values[param->paramno] = Z_STRVAL_P(parameter);
						S->param_lengths[param->paramno] = Z_STRLEN_P(parameter);
						S->param_formats[param->paramno] = 0;
					}

					if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
						S->param_types[param->paramno] = 0;
						S->param_formats[param->paramno] = 1;
					} else {
						S->param_types[param->paramno] = 0;
					}
				}
				break;
		}
	} else if (param->is_param) {
		/* We need to manually convert to a pg native boolean value */
		if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_BOOL &&
			((param->param_type & PDO_PARAM_INPUT_OUTPUT) != PDO_PARAM_INPUT_OUTPUT)) {
			SEPARATE_ZVAL(&param->parameter);
			param->param_type = PDO_PARAM_STR;
			convert_to_boolean(&param->parameter);
			ZVAL_STRINGL(&param->parameter, Z_TYPE_P(&param->parameter) == IS_TRUE ? "t" : "f", 1);
		}
	}
	return 1;
}
コード例 #8
0
ファイル: odbc_stmt.c プロジェクト: AmesianX/php-src
static int odbc_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param,
		enum pdo_param_event event_type)
{
	pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
	RETCODE rc;
	SWORD sqltype = 0, ctype = 0, scale = 0, nullable = 0;
	SQLULEN precision = 0;
	pdo_odbc_param *P;
	zval *parameter;
	
	/* we're only interested in parameters for prepared SQL right now */
	if (param->is_param) {

		switch (event_type) {
			case PDO_PARAM_EVT_FETCH_PRE:
			case PDO_PARAM_EVT_FETCH_POST:
			case PDO_PARAM_EVT_NORMALIZE:
				/* Do nothing */
				break;

			case PDO_PARAM_EVT_FREE:
				P = param->driver_data;
				if (P) {
					efree(P);
				}
				break;

			case PDO_PARAM_EVT_ALLOC:
			{
				/* figure out what we're doing */
				switch (PDO_PARAM_TYPE(param->param_type)) {
					case PDO_PARAM_LOB:
						break;

					case PDO_PARAM_STMT:
						return 0;
					
					default:
						break;
				}

				rc = SQLDescribeParam(S->stmt, (SQLUSMALLINT) param->paramno+1, &sqltype, &precision, &scale, &nullable);
				if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) {
					/* MS Access, for instance, doesn't support SQLDescribeParam,
					 * so we need to guess */
					sqltype = PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB ?
									SQL_LONGVARBINARY :
									SQL_LONGVARCHAR;
					precision = 4000;
					scale = 5;
					nullable = 1;

					if (param->max_value_len > 0) {
						precision = param->max_value_len;
					}
				}
				if (sqltype == SQL_BINARY || sqltype == SQL_VARBINARY || sqltype == SQL_LONGVARBINARY) {
					ctype = SQL_C_BINARY;
				} else {
					ctype = SQL_C_CHAR;
				}

				P = emalloc(sizeof(*P));
				param->driver_data = P;

				P->len = 0; /* is re-populated each EXEC_PRE */
				P->outbuf = NULL;

				P->is_unicode = pdo_odbc_sqltype_is_unicode(S, sqltype);
				if (P->is_unicode) {
					/* avoid driver auto-translation: we'll do it ourselves */
					ctype = SQL_C_BINARY;
				}

				if ((param->param_type & PDO_PARAM_INPUT_OUTPUT) == PDO_PARAM_INPUT_OUTPUT) {
					P->paramtype = SQL_PARAM_INPUT_OUTPUT;
				} else if (param->max_value_len <= 0) {
					P->paramtype = SQL_PARAM_INPUT;
				} else {
					P->paramtype = SQL_PARAM_OUTPUT;
				}
				
				if (P->paramtype != SQL_PARAM_INPUT) {
					if (PDO_PARAM_TYPE(param->param_type) != PDO_PARAM_NULL) {
						/* need an explicit buffer to hold result */
						P->len = param->max_value_len > 0 ? param->max_value_len : precision;
						if (P->is_unicode) {
							P->len *= 2;
						}
						P->outbuf = emalloc(P->len + (P->is_unicode ? 2:1));
					}
				}
				
				if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->paramtype != SQL_PARAM_INPUT) {
					pdo_odbc_stmt_error("Can't bind a lob for output");
					return 0;
				}

				rc = SQLBindParameter(S->stmt, (SQLUSMALLINT) param->paramno+1,
						P->paramtype, ctype, sqltype, precision, scale,
						P->paramtype == SQL_PARAM_INPUT ? 
							(SQLPOINTER)param :
							P->outbuf,
						P->len,
						&P->len
						);
	
				if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
					return 1;
				}
				pdo_odbc_stmt_error("SQLBindParameter");
				return 0;
			}

			case PDO_PARAM_EVT_EXEC_PRE:
				P = param->driver_data;
				if (!Z_ISREF(param->parameter)) {
					parameter = &param->parameter;
				} else {
					parameter = Z_REFVAL(param->parameter);
				}

				if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
					if (Z_TYPE_P(parameter) == IS_RESOURCE) {
						php_stream *stm;
						php_stream_statbuf sb;

						php_stream_from_zval_no_verify(stm, parameter);

						if (!stm) {
							return 0;
						}

						if (0 == php_stream_stat(stm, &sb)) {
							if (P->outbuf) {
								int len, amount;
								char *ptr = P->outbuf;
								char *end = P->outbuf + P->len;

								P->len = 0;
								do {
									amount = end - ptr;
									if (amount == 0) {
										break;
									}
									if (amount > 8192)
										amount = 8192;
									len = php_stream_read(stm, ptr, amount);
									if (len == 0) {
										break;
									}
									ptr += len;
									P->len += len;
								} while (1);

							} else {
								P->len = SQL_LEN_DATA_AT_EXEC(sb.sb.st_size);
							}
						} else {
							if (P->outbuf) {
								P->len = 0;
							} else {
								P->len = SQL_LEN_DATA_AT_EXEC(0);
							}
						}
					} else {
						convert_to_string(parameter);
						if (P->outbuf) {
							P->len = Z_STRLEN_P(parameter);
							memcpy(P->outbuf, Z_STRVAL_P(parameter), P->len);
						} else {
							P->len = SQL_LEN_DATA_AT_EXEC(Z_STRLEN_P(parameter));
						}
					}
				} else if (Z_TYPE_P(parameter) == IS_NULL || PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_NULL) {
					P->len = SQL_NULL_DATA;
				} else {
					convert_to_string(parameter);
					if (P->outbuf) {
						zend_ulong ulen;
						switch (pdo_odbc_utf82ucs2(stmt, P->is_unicode,
								Z_STRVAL_P(parameter),
								Z_STRLEN_P(parameter),
								&ulen)) {
							case PDO_ODBC_CONV_FAIL:
							case PDO_ODBC_CONV_NOT_REQUIRED:
								P->len = Z_STRLEN_P(parameter);
								memcpy(P->outbuf, Z_STRVAL_P(parameter), P->len);
								break;
							case PDO_ODBC_CONV_OK:
								P->len = ulen;
								memcpy(P->outbuf, S->convbuf, P->len);
								break;
						}
					} else {
						P->len = SQL_LEN_DATA_AT_EXEC(Z_STRLEN_P(parameter));
					}
				}
				return 1;
			
			case PDO_PARAM_EVT_EXEC_POST:
				P = param->driver_data;

				if (P->outbuf) {
					zend_ulong ulen;
					char *srcbuf;
					zend_ulong srclen = 0;

					if (Z_ISREF(param->parameter)) {
						parameter = Z_REFVAL(param->parameter);
					} else {
						parameter = &param->parameter;
					}
					zval_ptr_dtor(parameter);
					ZVAL_NULL(parameter);

					switch (P->len) {
						case SQL_NULL_DATA:
							break;
						default:
							switch (pdo_odbc_ucs22utf8(stmt, P->is_unicode, P->outbuf, P->len, &ulen)) {
								case PDO_ODBC_CONV_FAIL:
									/* something fishy, but allow it to come back as binary */
								case PDO_ODBC_CONV_NOT_REQUIRED:
									srcbuf = P->outbuf;
									srclen = P->len;
									break;
								case PDO_ODBC_CONV_OK:
									srcbuf = S->convbuf;
									srclen = ulen;
									break;
							}
										
							ZVAL_NEW_STR(parameter, zend_string_alloc(srclen, 0));
							memcpy(Z_STRVAL_P(parameter), srcbuf, srclen);
							Z_STRVAL_P(parameter)[Z_STRLEN_P(parameter)] = '\0';
					}
				}
				return 1;
		}
	}
	return 1;
}
コード例 #9
0
ファイル: odbc_stmt.c プロジェクト: AmesianX/php-src
static int odbc_stmt_execute(pdo_stmt_t *stmt)
{
	RETCODE rc;
	pdo_odbc_stmt *S = (pdo_odbc_stmt*)stmt->driver_data;
	char *buf = NULL;
	SQLLEN row_count = -1;

	if (stmt->executed) {
		SQLCloseCursor(S->stmt);
	}
	
	rc = SQLExecute(S->stmt);	

	while (rc == SQL_NEED_DATA) {
		struct pdo_bound_param_data *param;

		rc = SQLParamData(S->stmt, (SQLPOINTER*)&param);
		if (rc == SQL_NEED_DATA) {
			php_stream *stm;
			int len;
			pdo_odbc_param *P;
			zval *parameter;
	
			P = (pdo_odbc_param*)param->driver_data;
			if (Z_ISREF(param->parameter)) {
				parameter = Z_REFVAL(param->parameter);
			} else {
				parameter = &param->parameter;
			}
			if (Z_TYPE_P(parameter) != IS_RESOURCE) {
				/* they passed in a string */
				zend_ulong ulen;
				convert_to_string(parameter);

				switch (pdo_odbc_utf82ucs2(stmt, P->is_unicode, 
							Z_STRVAL_P(parameter),
							Z_STRLEN_P(parameter),
							&ulen)) {
					case PDO_ODBC_CONV_NOT_REQUIRED:
						SQLPutData(S->stmt, Z_STRVAL_P(parameter),
							Z_STRLEN_P(parameter));
						break;
					case PDO_ODBC_CONV_OK:
						SQLPutData(S->stmt, S->convbuf, ulen);
						break;
					case PDO_ODBC_CONV_FAIL:
						pdo_odbc_stmt_error("error converting input string");
						SQLCloseCursor(S->stmt);
						if (buf) {
							efree(buf);
						}
						return 0;
				}
				continue;
			}

			/* we assume that LOBs are binary and don't need charset
			 * conversion */

			php_stream_from_zval_no_verify(stm, parameter);
			if (!stm) {
				/* shouldn't happen either */
				pdo_odbc_stmt_error("input LOB is no longer a stream");
				SQLCloseCursor(S->stmt);
				if (buf) {
					efree(buf);
				}
				return 0;
			}

			/* now suck data from the stream and stick it into the database */
			if (buf == NULL) {
				buf = emalloc(8192);
			}

			do {
				len = php_stream_read(stm, buf, 8192);
				if (len == 0) {
					break;
				}
				SQLPutData(S->stmt, buf, len);
			} while (1);
		}
	}

	if (buf) {
		efree(buf);
	}

	switch (rc) {
		case SQL_SUCCESS:
			break;
		case SQL_NO_DATA_FOUND:
		case SQL_SUCCESS_WITH_INFO:
			pdo_odbc_stmt_error("SQLExecute");
			break;

		default:
			pdo_odbc_stmt_error("SQLExecute");
			return 0;
	}

	SQLRowCount(S->stmt, &row_count);
	stmt->row_count = row_count;

	if (!stmt->executed) {
		/* do first-time-only definition of bind/mapping stuff */
		SQLSMALLINT colcount;

		/* how many columns do we have ? */
		SQLNumResultCols(S->stmt, &colcount);

		stmt->column_count = (int)colcount;
		S->cols = ecalloc(colcount, sizeof(pdo_odbc_column));
		S->going_long = 0;
	}

	return 1;
}
コード例 #10
0
ファイル: oci_statement.c プロジェクト: dzuelke/php-src
static int oci_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, enum pdo_param_event event_type) /* {{{ */
{
	pdo_oci_stmt *S = (pdo_oci_stmt*)stmt->driver_data;

	/* we're only interested in parameters for prepared SQL right now */
	if (param->is_param) {
		pdo_oci_bound_param *P;
		sb4 value_sz = -1;
		zval *parameter;

		if (Z_ISREF(param->parameter))
			parameter = Z_REFVAL(param->parameter);
		else
			parameter = &param->parameter;

		P = (pdo_oci_bound_param*)param->driver_data;

		switch (event_type) {
			case PDO_PARAM_EVT_FETCH_PRE:
			case PDO_PARAM_EVT_FETCH_POST:
			case PDO_PARAM_EVT_NORMALIZE:
				/* Do nothing */
				break;

			case PDO_PARAM_EVT_FREE:
				P = param->driver_data;
				if (P && P->thing) {
					OCI_TEMPLOB_CLOSE(S->H->env, S->H->svc, S->H->err, P->thing);
					OCIDescriptorFree(P->thing, OCI_DTYPE_LOB);
					P->thing = NULL;
					efree(P);
				}
				else if (P) {
					efree(P);
				}
				break;

			case PDO_PARAM_EVT_ALLOC:
				P = (pdo_oci_bound_param*)ecalloc(1, sizeof(pdo_oci_bound_param));
				param->driver_data = P;

				/* figure out what we're doing */
				switch (PDO_PARAM_TYPE(param->param_type)) {
					case PDO_PARAM_STMT:
						return 0;

					case PDO_PARAM_LOB:
						/* P->thing is now an OCILobLocator * */
						P->oci_type = SQLT_BLOB;
						value_sz = (sb4) sizeof(OCILobLocator*);
						break;

					case PDO_PARAM_STR:
					default:
						P->oci_type = SQLT_CHR;
						value_sz = (sb4) param->max_value_len;
						if (param->max_value_len == 0) {
							value_sz = (sb4) 1332; /* maximum size before value is interpreted as a LONG value */
						}

				}

				if (param->name) {
					STMT_CALL(OCIBindByName, (S->stmt,
							&P->bind, S->err, (text*)param->name->val,
							(sb4) param->name->len, 0, value_sz, P->oci_type,
							&P->indicator, 0, &P->retcode, 0, 0,
							OCI_DATA_AT_EXEC));
				} else {
					STMT_CALL(OCIBindByPos, (S->stmt,
							&P->bind, S->err, ((ub4)param->paramno)+1,
							0, value_sz, P->oci_type,
							&P->indicator, 0, &P->retcode, 0, 0,
							OCI_DATA_AT_EXEC));
				}

				STMT_CALL(OCIBindDynamic, (P->bind,
							S->err,
							param, oci_bind_input_cb,
							param, oci_bind_output_cb));

				return 1;

			case PDO_PARAM_EVT_EXEC_PRE:
				P->indicator = 0;
				P->used_for_output = 0;
				if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB) {
					ub4 empty = 0;
					STMT_CALL(OCIDescriptorAlloc, (S->H->env, &P->thing, OCI_DTYPE_LOB, 0, NULL));
					STMT_CALL(OCIAttrSet, (P->thing, OCI_DTYPE_LOB, &empty, 0, OCI_ATTR_LOBEMPTY, S->err));
					S->have_blobs = 1;
				}
				return 1;

			case PDO_PARAM_EVT_EXEC_POST:
				/* fixup stuff set in motion in oci_bind_output_cb */
				if (P->used_for_output) {
					if (P->indicator == -1) {
						/* set up a NULL value */
						if (Z_TYPE_P(parameter) == IS_STRING) {
							/* OCI likes to stick non-terminated strings in things */
							*Z_STRVAL_P(parameter) = '\0';
						}
						zval_dtor(parameter);
						ZVAL_UNDEF(parameter);
					} else if (Z_TYPE_P(parameter) == IS_STRING) {
						Z_STR_P(parameter) = zend_string_init(Z_STRVAL_P(parameter), P->actual_len, 1);
					}
				} else if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_LOB && P->thing) {
					php_stream *stm;

					if (Z_TYPE_P(parameter) == IS_NULL) {
						/* if the param is NULL, then we assume that they
						 * wanted to bind a lob locator into it from the query
						 * */

						stm = oci_create_lob_stream(&stmt->database_object_handle, stmt, (OCILobLocator*)P->thing);
						if (stm) {
							OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
							php_stream_to_zval(stm, parameter);
						}
					} else {
						/* we're a LOB being used for insert; transfer the data now */
						size_t n;
						ub4 amt, offset = 1;
						char *consume;

						php_stream_from_zval_no_verify(stm, parameter);
						if (stm) {
							OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
							do {
								char buf[8192];
								n = php_stream_read(stm, buf, sizeof(buf));
								if ((int)n <= 0) {
									break;
								}
								consume = buf;
								do {
									amt = (ub4) n;
									OCILobWrite(S->H->svc, S->err, (OCILobLocator*)P->thing,
											&amt, offset, consume, (ub4) n,
											OCI_ONE_PIECE,
											NULL, NULL, 0, SQLCS_IMPLICIT);
									offset += amt;
									n -= amt;
									consume += amt;
								} while (n);
							} while (1);
							OCILobClose(S->H->svc, S->err, (OCILobLocator*)P->thing);
							OCILobFlushBuffer(S->H->svc, S->err, (OCILobLocator*)P->thing, 0);
						} else if (Z_TYPE_P(parameter) == IS_STRING) {
							/* stick the string into the LOB */
							consume = Z_STRVAL_P(parameter);
							n = Z_STRLEN_P(parameter);
							if (n) {
								OCILobOpen(S->H->svc, S->err, (OCILobLocator*)P->thing, OCI_LOB_READWRITE);
								while (n) {
									amt = (ub4) n;
									OCILobWrite(S->H->svc, S->err, (OCILobLocator*)P->thing,
											&amt, offset, consume, (ub4) n,
											OCI_ONE_PIECE,
											NULL, NULL, 0, SQLCS_IMPLICIT);
									consume += amt;
									n -= amt;
								}
								OCILobClose(S->H->svc, S->err, (OCILobLocator*)P->thing);
							}
						}
						OCI_TEMPLOB_CLOSE(S->H->env, S->H->svc, S->H->err, P->thing);
						OCIDescriptorFree(P->thing, OCI_DTYPE_LOB);
						P->thing = NULL;
					}
				}

				return 1;
		}
	}

	return 1;
} /* }}} */
コード例 #11
0
ファイル: mysqlnd_ps_codec.c プロジェクト: Sobak/php-src
/* {{{ mysqlnd_stmt_execute_calculate_param_values_size */
static enum_func_status
mysqlnd_stmt_execute_calculate_param_values_size(MYSQLND_STMT_DATA * stmt, zval ** copies_param, size_t * data_size)
{
	unsigned int i;
	DBG_ENTER("mysqlnd_stmt_execute_calculate_param_values_size");
	for (i = 0; i < stmt->param_count; i++) {
		unsigned short is_longlong = 0;
		unsigned int j;
		zval *bind_var, *the_var = &stmt->param_bind[i].zv;

		bind_var = the_var;
		ZVAL_DEREF(the_var);
		if ((stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB && Z_TYPE_P(the_var) == IS_NULL)) {
			continue;
		}

		if (Z_ISREF_P(bind_var)) {
			for (j = i + 1; j < stmt->param_count; j++) {
				if (Z_ISREF(stmt->param_bind[j].zv) && Z_REFVAL(stmt->param_bind[j].zv) == the_var) {
					/* Double binding of the same zval, make a copy */
					if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
						if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
							SET_OOM_ERROR(*stmt->error_info);
							goto end;
						}
					}
					break;
				}
			}
		}

		switch (stmt->param_bind[i].type) {
			case MYSQL_TYPE_DOUBLE:
				*data_size += 8;
				if (Z_TYPE_P(the_var) != IS_DOUBLE) {
					if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
						if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
							SET_OOM_ERROR(*stmt->error_info);
							goto end;
						}
					}
				}
				break;
			case MYSQL_TYPE_LONGLONG:
				is_longlong = 4;
				/* fall-through */
			case MYSQL_TYPE_LONG:
				{
					zval *tmp_data = (*copies_param && !Z_ISUNDEF((*copies_param)[i]))? &(*copies_param)[i]: the_var;
					if (Z_TYPE_P(tmp_data) == IS_STRING) {
						goto use_string;
					}
					convert_to_long_ex(tmp_data);
				}
				*data_size += 4 + is_longlong;
				break;
			case MYSQL_TYPE_LONG_BLOB:
				if (!(stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED)) {
					/*
					  User hasn't sent anything, we will send empty string.
					  Empty string has length of 0, encoded in 1 byte. No real
					  data will follows after it.
					*/
					(*data_size)++;
				}
				break;
			case MYSQL_TYPE_VAR_STRING:
use_string:
				*data_size += 8; /* max 8 bytes for size */
				if (Z_TYPE_P(the_var) != IS_STRING) {
					if (!*copies_param || Z_ISUNDEF((*copies_param)[i])) {
						if (PASS != mysqlnd_stmt_copy_it(copies_param, the_var, stmt->param_count, i)) {
							SET_OOM_ERROR(*stmt->error_info);
							goto end;
						}
					}
					the_var = &((*copies_param)[i]);
				}
				convert_to_string_ex(the_var);
				*data_size += Z_STRLEN_P(the_var);
				break;
		}
	}
	DBG_RETURN(PASS);
end:
	DBG_RETURN(FAIL);
}