Esempio n. 1
0
/* {{{ */
static void collator_ctor(INTERNAL_FUNCTION_PARAMETERS)
{
	char*            locale;
	int              locale_len = 0;
	zval*            object;
	Collator_object* co;

	intl_error_reset( NULL TSRMLS_CC );
	object = return_value;
	/* Parse parameters. */
	if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s",
		&locale, &locale_len ) == FAILURE )
	{
		intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
			"collator_create: unable to parse input params", 0 TSRMLS_CC );
		zval_dtor(return_value);
		RETURN_NULL();
	}

	INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
	co = (Collator_object *) zend_object_store_get_object( object TSRMLS_CC );

	intl_error_reset( COLLATOR_ERROR_P( co ) TSRMLS_CC );

	if(locale_len == 0) {
		locale = UG(default_locale);
	}

	/* Open ICU collator. */
	co->ucoll = ucol_open( locale, COLLATOR_ERROR_CODE_P( co ) );
	INTL_CTOR_CHECK_STATUS(co, "collator_create: unable to open ICU collator");
}
Esempio n. 2
0
PHPAPI void mysqlnd_minfo_print_hash(zval *values)
{
	zval **values_entry;
	HashPosition pos_values;

	zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos_values);
	while (zend_hash_get_current_data_ex(Z_ARRVAL_P(values),
		(void **)&values_entry, &pos_values) == SUCCESS) {
		zstr	string_key;
		uint	string_key_len;
		ulong	num_key;
		int		s_len;
		char	*s = NULL;

		TSRMLS_FETCH();
		zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &string_key, &string_key_len, &num_key, 0, &pos_values);

		convert_to_string(*values_entry);

		if (zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)),
								   &s, &s_len, string_key.u, string_key_len TSRMLS_CC) == SUCCESS) {
			php_info_print_table_row(2, s, Z_STRVAL_PP(values_entry));
		}
		if (s) {
			mnd_efree(s);
		}

		zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos_values);
	}
}
Esempio n. 3
0
static int php_info_uprint_html_esc(const UChar *str, int len) /* {{{ */
{
    UErrorCode status = U_ZERO_ERROR;
    char *new_str = NULL;
    int new_len, written;
    TSRMLS_FETCH();

    zend_unicode_to_string_ex(UG(utf8_conv), &new_str, &new_len, str, len, &status);
    if (U_FAILURE(status)) {
        return 0;
    }
    written = php_info_print_html_esc(new_str, new_len);
    efree(new_str);
    return written;
}
Esempio n. 4
0
/* {{{ mysqlnd_stmt_execute_store_params */
static void
mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar **p,
								  size_t *buf_len, unsigned int null_byte_offset TSRMLS_DC)
{
	MYSQLND_STMT_DATA * stmt = s->data;
	unsigned int i = 0;
	size_t left = (*buf_len - (*p - *buf));
	size_t data_size = 0;
	zval **copies = NULL;/* if there are different types */

/* 1. Store type information */
	if (stmt->send_types_to_server) {

		/* 2 bytes per type, and leave 20 bytes for future use */
		if (left < ((stmt->param_count * 2) + 20)) {
			unsigned int offset = *p - *buf;
			zend_uchar *tmp_buf;
			*buf_len = offset + stmt->param_count * 2 + 20;
			tmp_buf = mnd_emalloc(*buf_len);
			memcpy(tmp_buf, *buf, offset);
			*buf = tmp_buf;
			
			/* Update our pos pointer */
			*p = *buf + offset;
		}
		for (i = 0; i < stmt->param_count; i++) {
			/* our types are not unsigned */
#if SIZEOF_LONG==8  
			if (stmt->param_bind[i].type == MYSQL_TYPE_LONG) {
				stmt->param_bind[i].type = MYSQL_TYPE_LONGLONG;
			}
#endif
			int2store(*p, stmt->param_bind[i].type);
			*p+= 2;
		}
	}

/* 2. Store data */
	/* 2.1 Calculate how much space we need */
	for (i = 0; i < stmt->param_count; i++) {
		unsigned int j;
		zval *the_var = stmt->param_bind[i].zv;

		if (!the_var || (stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB &&
						 Z_TYPE_P(the_var) == IS_NULL)) {
			continue;
		}
		for (j = i + 1; j < stmt->param_count; j++) {
			if (stmt->param_bind[j].zv == the_var) {
				/* Double binding of the same zval, make a copy */
				mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC);
				break; 
			}
		}

		switch (stmt->param_bind[i].type) {
			case MYSQL_TYPE_DOUBLE:
				data_size += 8;
				if (Z_TYPE_P(the_var) != IS_DOUBLE) {
					if (!copies || !copies[i]) {
						mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC);
					}
				}
				break;
#if SIZEOF_LONG==8  
			case MYSQL_TYPE_LONGLONG:
				data_size += 8;
#elif SIZEOF_LONG==4
			case MYSQL_TYPE_LONG:
				data_size += 4;
#else
#error "Should not happen"
#endif
				if (Z_TYPE_P(the_var) != IS_LONG) {
					if (!copies || !copies[i]) {
						mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC);
					}
				}
				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:
				data_size += 8; /* max 8 bytes for size */
#if PHP_MAJOR_VERSION < 6
				if (Z_TYPE_P(the_var) != IS_STRING)
#elif PHP_MAJOR_VERSION >= 6
				if (Z_TYPE_P(the_var) != IS_STRING || Z_TYPE_P(the_var) == IS_UNICODE)
#endif
				{
					if (!copies || !copies[i]) {
						mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC);
					}
					the_var = copies[i];
#if PHP_MAJOR_VERSION >= 6
					if (Z_TYPE_P(the_var) == IS_UNICODE) {
						zval_unicode_to_string_ex(the_var, UG(utf8_conv) TSRMLS_CC);
					}
#endif
				}
				convert_to_string_ex(&the_var);
				data_size += Z_STRLEN_P(the_var);
				break;
		}

	}

	/* 2.2 Enlarge the buffer, if needed */
	left = (*buf_len - (*p - *buf));
	if (left < data_size) {
		unsigned int offset = *p - *buf;
		zend_uchar *tmp_buf;
		*buf_len = offset + data_size + 10; /* Allocate + 10 for safety */
		tmp_buf = mnd_emalloc(*buf_len);
		memcpy(tmp_buf, *buf, offset);
		*buf = tmp_buf;
		/* Update our pos pointer */
		*p = *buf + offset;	
	}

	/* 2.3 Store the actual data */
	for (i = 0; i < stmt->param_count; i++) {
		zval *data = copies && copies[i]? copies[i]: stmt->param_bind[i].zv;
		/* Handle long data */
		if (stmt->param_bind[i].zv && Z_TYPE_P(data) == IS_NULL) {
			(*buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
		} else {
			switch (stmt->param_bind[i].type) {
				case MYSQL_TYPE_DOUBLE:
					convert_to_double_ex(&data);
					float8store(*p, Z_DVAL_P(data));
					(*p) += 8;
					break;
#if SIZEOF_LONG==8  
				case MYSQL_TYPE_LONGLONG:
					convert_to_long_ex(&data);
					int8store(*p, Z_LVAL_P(data));
					(*p) += 8;
					break;
#elif SIZEOF_LONG==4
				case MYSQL_TYPE_LONG:
					convert_to_long_ex(&data);
					int4store(*p, Z_LVAL_P(data));
					(*p) += 4;
					break;
#else
#error "Should not happen"
#endif
				case MYSQL_TYPE_LONG_BLOB:
					if (stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED) {
						stmt->param_bind[i].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED;
					} else {
						/* send_long_data() not called, send empty string */
						*p = php_mysqlnd_net_store_length(*p, 0);
					}
					break;
				case MYSQL_TYPE_VAR_STRING:{
						unsigned int len = Z_STRLEN_P(data);
						/* to is after p. The latter hasn't been moved */
						*p = php_mysqlnd_net_store_length(*p, len);
						memcpy(*p, Z_STRVAL_P(data), len);
						(*p) += len;
					}
					break;
				default:
					/* Won't happen, but set to NULL */
					(*buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
					break;
			}
		}
	}
	if (copies) {
		for (i = 0; i < stmt->param_count; i++) {
			if (copies[i]) {
				zval_ptr_dtor(&copies[i]);
			}
		}
		mnd_efree(copies);	
	}
}
Esempio n. 5
0
/* {{{ proto DOMDocumentType dom_domimplementation_create_document_type(string qualifiedName, string publicId, string systemId) U
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocType
Since: DOM Level 2
*/
PHP_METHOD(domimplementation, createDocumentType)
{
    zval *rv = NULL;
    xmlDtd *doctype;
    int ret, name_len = 0, publicid_len = 0, systemid_len = 0;
    char *name = NULL, *publicid = NULL, *systemid = NULL;
    xmlChar *pch1 = NULL, *pch2 = NULL, *localname = NULL;
    xmlURIPtr uri;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s&s&s&", &name, &name_len, UG(utf8_conv), &publicid, &publicid_len, UG(utf8_conv), &systemid, &systemid_len, UG(utf8_conv)) == FAILURE) {
        return;
    }

    if (name_len == 0) {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "qualifiedName is required");
        RETURN_FALSE;
    }

    if (publicid_len > 0)
        pch1 = publicid;
    if (systemid_len > 0)
        pch2 = systemid;

    uri = xmlParseURI(name);
    if (uri != NULL && uri->opaque != NULL) {
        localname = xmlStrdup(uri->opaque);
        if (xmlStrchr(localname, (xmlChar) ':') != NULL) {
            php_dom_throw_error(NAMESPACE_ERR, 1 TSRMLS_CC);
            xmlFreeURI(uri);
            xmlFree(localname);
            RETURN_FALSE;
        }
    } else {
        localname = xmlStrdup(name);
    }

    /* TODO: Test that localname has no invalid chars
    php_dom_throw_error(INVALID_CHARACTER_ERR, TSRMLS_CC);
    */

    if (uri) {
        xmlFreeURI(uri);
    }

    doctype = xmlCreateIntSubset(NULL, localname, pch1, pch2);
    xmlFree(localname);

    if (doctype == NULL) {
        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create DocumentType");
        RETURN_FALSE;
    }

    DOM_RET_OBJ(rv, (xmlNodePtr) doctype, &ret, NULL);
}
Esempio n. 6
0
/* {{{ proto DOMDocument dom_domimplementation_create_document(string namespaceURI, string qualifiedName, DOMDocumentType doctype) U
URL: http://www.w3.org/TR/2003/WD-DOM-Level-3-Core-20030226/DOM3-Core.html#Level-2-Core-DOM-createDocument
Since: DOM Level 2
*/
PHP_METHOD(domimplementation, createDocument)
{
    zval *node = NULL, *rv = NULL;
    xmlDoc *docp;
    xmlNode *nodep;
    xmlDtdPtr doctype = NULL;
    xmlNsPtr nsptr = NULL;
    int ret, uri_len = 0, name_len = 0, errorcode = 0;
    char *uri = NULL, *name = NULL;
    char *prefix = NULL, *localname = NULL;
    dom_object *doctobj;

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s&s&O", &uri, &uri_len, UG(utf8_conv), &name, &name_len, UG(utf8_conv), &node, dom_documenttype_class_entry) == FAILURE) {
        return;
    }

    if (node != NULL) {
        DOM_GET_OBJ(doctype, node, xmlDtdPtr, doctobj);
        if (doctype->type == XML_DOCUMENT_TYPE_NODE) {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid DocumentType object");
            RETURN_FALSE;
        }
        if (doctype->doc != NULL) {
            php_dom_throw_error(WRONG_DOCUMENT_ERR, 1 TSRMLS_CC);
            RETURN_FALSE;
        }
    } else {
        doctobj = NULL;
    }

    if (name_len > 0) {
        errorcode = dom_check_qname(name, &localname, &prefix, 1, name_len);
        if (errorcode == 0 && uri_len > 0 && ((nsptr = xmlNewNs(NULL, uri, prefix)) == NULL)) {
            errorcode = NAMESPACE_ERR;
        }
    }

    if (prefix != NULL) {
        xmlFree(prefix);
    }

    if (errorcode != 0) {
        if (localname != NULL) {
            xmlFree(localname);
        }
        php_dom_throw_error(errorcode, 1 TSRMLS_CC);
        RETURN_FALSE;
    }

    /* currently letting libxml2 set the version string */
    docp = xmlNewDoc(NULL);
    if (!docp) {
        if (localname != NULL) {
            xmlFree(localname);
        }
        RETURN_FALSE;
    }

    if (doctype != NULL) {
        docp->intSubset = doctype;
        doctype->parent = docp;
        doctype->doc = docp;
        docp->children = (xmlNodePtr) doctype;
        docp->last = (xmlNodePtr) doctype;
    }

    if (localname != NULL) {
        nodep = xmlNewDocNode (docp, nsptr, localname, NULL);
        if (!nodep) {
            if (doctype != NULL) {
                docp->intSubset = NULL;
                doctype->parent = NULL;
                doctype->doc = NULL;
                docp->children = NULL;
                docp->last = NULL;
            }
            xmlFreeDoc(docp);
            xmlFree(localname);
            /* Need some type of error here */
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unexpected Error");
            RETURN_FALSE;
        }

        nodep->nsDef = nsptr;

        xmlDocSetRootElement(docp, nodep);
        xmlFree(localname);
    }

    DOM_RET_OBJ(rv, (xmlNodePtr) docp, &ret, NULL);

    if (doctobj != NULL) {
        doctobj->document = ((dom_object *)((php_libxml_node_ptr *)docp->_private)->_private)->document;
        php_libxml_increment_doc_ref((php_libxml_node_object *)doctobj, docp TSRMLS_CC);
    }
}
void write_scaled_labeled_graphviz(Graph & G, string output_file, vector<double> color, vector<size_t> sizes, bool directed)
{
  ofstream output;
  output.open(output_file.c_str());

  double color_min = color[0];
  double color_max = color[0];
  size_t size_min = sizes[0];
  size_t size_max = sizes[0];

  v_size_t n = num_vertices(G);

  if (color.size() != sizes.size() || color.size() != n)
    {
      cout<<"Color vector, size vector must all be of length num_nodes in graph. Exiting. \n";
      exit(EXIT_FAILURE);
    }

  for (size_t i = 0; i < color.size(); ++i)
    {
      if(color[i] > color_max)
	color_max = color[i];

      if(color[i] < color_min)
	color_min = color[i];

      if(sizes[i] > size_max)
	size_max = sizes[i];

      if(sizes[i] < size_min)
	size_min = sizes[i];
    }

  if (color_max > 1 or color_min < 0)
    {
      cout<<"Color vector must be in range [0,1]. Exiting.\n";
      exit(EXIT_FAILURE);
    }

  output<<"Graph color {\n";
  output<<"splines=false;\n";

  graph_traits<Graph>::edge_iterator eit, eitend;
  graph_traits<Graph>::vertex_iterator vit, vitend;

  property_map<Graph, vertex_index_t>::type index = get(vertex_index,G);

  for(tie(vit,vitend)=vertices(G);vit!=vitend;++vit)
    {
      Vert      v = *vit;
      v_size_t vi = index[v];
      char rgb[8];
      double width = .75;
      if (size_max != size_min)
	width = 0.1 + ((double) sizes[vi] - size_min) / (double) (size_max - size_min);
      
      double val = 0.5;

      val = color[vi];
      
      get_rgb_value(rgb, val);
      stringstream ss;

      string label;
      ss<<vi;
      ss>>label;

      output<<vi<<"[label=\""<<label<<"\", width="<<width<<", shape=circle, style=\"filled\", fillcolor=\""<<rgb<<"\"];\n";

    }
  
  if(directed)
    {
      for(tie(eit,eitend)=edges(G);eit!=eitend;++eit)
	{
	  Edge e = *eit;
	  Vert u,v;
	  u = source(e,G);
	  v = target(e,G);

	  v_size_t ui = index[u];
	  v_size_t vi = index[v];

	  output<<ui<<" -- "<<vi<<";\n";
	}
    }
  else
    {
      cout<<"Graph viz undirected\n";
      UGraph UG((v_Usize_t) n );

      for(tie(eit,eitend)=edges(G);eit!=eitend;++eit)
	{
	  Edge e = *eit;
	  Vert s = source(e,G);
	  Vert t = target(e,G);

	  //	  cout<<"s "<<s<<" t "<<t<<"\n";

	  long ui = index[s];
	  long vi = index[t];

	  //cout<<"ui "<<ui<<" vi "<<vi<<"\n";

	  UVert u = vertex(ui,UG);
	  UVert v = vertex(vi,UG);

	  //cout<<"u "<<u<<" v "<<v<<"\n";

	  UEdge exist;
	  bool yes1,yes2;

	  tie(exist,yes1) = edge(u,v,UG);
	  tie(exist,yes2) = edge(v,u,UG);
	  if(!yes1 && !yes2)
	    add_edge(u,v,UG);
	}

      graph_traits<UGraph>::edge_iterator uit, uitend;
      property_map<UGraph, vertex_index_t>::type u_index = get(vertex_index,UG);

      for(tie(uit,uitend)=edges(UG);uit!=uitend;++uit)
	{
	  UEdge e = *uit;
	  UVert u,v;
	  u = source(e,UG);
	  v = target(e,UG);

	  long ui = u_index[u];
	  long vi = u_index[v];

	  output<<ui<<" -- "<<vi<<";\n";
	}
    }

  output<<"}";
  output.close();
}
/*
  This function produces a graphviz file of the graph passed to it,
  but it colors the nodes based on the colors provided in color.  All
  nodes are same size, though the nodes in the vector square_nodes are
  doubled in size and square as a way of highlighting important nodes.
 */
void write_graphviz(Graph & G, string output_file, vector<double> color, vector<int> square_nodes, bool directed)
{
  ofstream output;
  output.open(output_file.c_str());

  double min = color[0];
  double max = color[0];

  v_size_t n = num_vertices(G);

  for(size_t i = 0; i < color.size(); ++i)
    {
      if(color[i]>max)
	max = color[i];

      if(color[i]<min)
	min = color[i];
    }


  output<<"Graph color {\n";
  output<<"splines=false;\n";

  graph_traits<Graph>::edge_iterator eit, eitend;
  graph_traits<Graph>::vertex_iterator vit, vitend;

  property_map<Graph, vertex_index_t>::type index = get(vertex_index,G);

  for (tie(vit,vitend) = vertices(G); vit != vitend; ++vit)
    {

      Vert      v = *vit;
      v_size_t vi = index[v];
      char rgb[8];
      double width=0.2;      
      double val;
      
      if (color.size() != n && G[v].prevIndices.size() != 0)
	val = ((double) color[G[v].prevIndices[0]] - min) / (double) (max - min);
      else
	val = ((double) color[vi] - min) / (double) (max - min);

      get_rgb_value(rgb,val);

      int found = binarySearch(square_nodes,vi);
      
      if(found==-1)
	output<<vi<<"[label=\"\", width="<<width<<", shape=circle, style=\"filled\", fillcolor=\""<<rgb<<"\"];\n";
      else
	output<<vi<<"[label=\"\", width="<<2.0*width<<", shape=square, style=\"filled\", fillcolor=\""<<rgb<<"\"];\n";

    }
  
  if(directed)
    {
      for(tie(eit,eitend)=edges(G);eit!=eitend;++eit)
	{
	  Edge e = *eit;
	  Vert u,v;
	  u = source(e,G);
	  v = target(e,G);

	  v_size_t ui = index[u];
	  v_size_t vi = index[v];

	  output<<ui<<" -- "<<vi<<";\n";
	}
    }
  else
    {
      cout<<"Graph viz undirected\n";
      UGraph UG((v_Usize_t) n );

      for(tie(eit,eitend)=edges(G);eit!=eitend;++eit)
	{
	  Edge e = *eit;
	  Vert s = source(e,G);
	  Vert t = target(e,G);

	  //	  cout<<"s "<<s<<" t "<<t<<"\n";

	  long ui = index[s];
	  long vi = index[t];

	  //cout<<"ui "<<ui<<" vi "<<vi<<"\n";

	  UVert u = vertex(ui,UG);
	  UVert v = vertex(vi,UG);

	  //cout<<"u "<<u<<" v "<<v<<"\n";

	  UEdge exist;
	  bool yes1,yes2;

	  tie(exist,yes1) = edge(u,v,UG);
	  tie(exist,yes2) = edge(v,u,UG);
	  if(!yes1 && !yes2)
	    add_edge(u,v,UG);
	}

      graph_traits<UGraph>::edge_iterator uit, uitend;
      property_map<UGraph, vertex_index_t>::type u_index = get(vertex_index,UG);

      for(tie(uit,uitend)=edges(UG);uit!=uitend;++uit)
	{
	  UEdge e = *uit;
	  UVert u,v;
	  u = source(e,UG);
	  v = target(e,UG);

	  long ui = u_index[u];
	  long vi = u_index[v];

	  output<<ui<<" -- "<<vi<<";\n";
	}
    }

  output<<"}";
  output.close();
}
/* {{{ proto void DOMProcessingInstruction::__construct(string name, [string value]) U */
PHP_METHOD(domprocessinginstruction, __construct)
{

    zval *id;
    xmlNodePtr nodep = NULL, oldnode = NULL;
    dom_object *intern;
    char *name, *value = NULL;
    int name_len, value_len, name_valid;
    zend_error_handling error_handling;

    zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
    if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os&|s&", &id, dom_processinginstruction_class_entry, &name, &name_len, UG(utf8_conv), &value, &value_len, UG(utf8_conv)) == FAILURE) {
        zend_restore_error_handling(&error_handling TSRMLS_CC);
        return;
    }
    zend_restore_error_handling(&error_handling TSRMLS_CC);

    name_valid = xmlValidateName((xmlChar *) name, 0);
    if (name_valid != 0) {
        php_dom_throw_error(INVALID_CHARACTER_ERR, 1 TSRMLS_CC);
        RETURN_FALSE;
    }

    nodep = xmlNewPI((xmlChar *) name, (xmlChar *) value);

    if (!nodep) {
        php_dom_throw_error(INVALID_STATE_ERR, 1 TSRMLS_CC);
        RETURN_FALSE;
    }

    intern = (dom_object *)zend_object_store_get_object(id TSRMLS_CC);
    if (intern != NULL) {
        oldnode = dom_object_get_node(intern);
        if (oldnode != NULL) {
            php_libxml_node_free_resource(oldnode  TSRMLS_CC);
        }
        php_libxml_increment_node_ptr((php_libxml_node_object *)intern, nodep, (void *)intern TSRMLS_CC);
    }
}
Esempio n. 10
0
/* {{{ mysqlnd_stmt_execute_store_params */
static enum_func_status
mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar **p,
								  size_t *buf_len, unsigned int null_byte_offset TSRMLS_DC)
{
	MYSQLND_STMT_DATA * stmt = s->data;
	unsigned int i = 0;
	zend_uchar * provided_buffer = *buf;
	size_t left = (*buf_len - (*p - *buf));
	size_t data_size = 0;
	zval **copies = NULL;/* if there are different types */
	enum_func_status ret = FAIL;
	int resend_types_next_time = 0;

	DBG_ENTER("mysqlnd_stmt_execute_store_params");

/* 1. Store type information */
	/*
	  check if need to send the types even if stmt->send_types_to_server is 0. This is because
	  if we send "i" (42) then the type will be int and the server will expect int. However, if next
	  time we try to send > LONG_MAX, the conversion to string will send a string and the server
	  won't expect it and interpret the value as 0. Thus we need to resend the types, if any such values
	  occur, and force resend for the next execution.
	*/
	for (i = 0; i < stmt->param_count; i++) {
		if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL &&
			(stmt->param_bind[i].type == MYSQL_TYPE_LONG || stmt->param_bind[i].type == MYSQL_TYPE_LONGLONG))
		{
			/* always copy the var, because we do many conversions */
			if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG &&
				PASS != mysqlnd_stmt_copy_it(&copies, stmt->param_bind[i].zv, stmt->param_count, i TSRMLS_CC))
			{
				SET_OOM_ERROR(stmt->error_info);
				goto end;
			}
			/*
			  if it doesn't fit in a long send it as a string.
			  Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
			*/
			if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) {
				zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
				convert_to_double_ex(&tmp_data);
				if (Z_DVAL_P(tmp_data) > LONG_MAX || Z_DVAL_P(tmp_data) < LONG_MIN) {
					stmt->send_types_to_server = resend_types_next_time = 1;
				}
			}
		}
	}

	int1store(*p, stmt->send_types_to_server); 
	(*p)++;

	if (stmt->send_types_to_server) {
		/* 2 bytes per type, and leave 20 bytes for future use */
		if (left < ((stmt->param_count * 2) + 20)) {
			unsigned int offset = *p - *buf;
			zend_uchar *tmp_buf;
			*buf_len = offset + stmt->param_count * 2 + 20;
			tmp_buf = mnd_emalloc(*buf_len);
			if (!tmp_buf) {
				SET_OOM_ERROR(stmt->error_info);
				goto end;
			}
			memcpy(tmp_buf, *buf, offset);
			*buf = tmp_buf;

			/* Update our pos pointer */
			*p = *buf + offset;
		}
		for (i = 0; i < stmt->param_count; i++) {
			short current_type = stmt->param_bind[i].type;
			/* our types are not unsigned */
#if SIZEOF_LONG==8  
			if (current_type == MYSQL_TYPE_LONG) {
				current_type = MYSQL_TYPE_LONGLONG;
			}
#endif
			if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_NULL && (current_type == MYSQL_TYPE_LONG || current_type == MYSQL_TYPE_LONGLONG)) {
				/*
				  if it doesn't fit in a long send it as a string.
				  Check bug #52891 : Wrong data inserted with mysqli/mysqlnd when using bind_param, value > LONG_MAX
				*/
				if (Z_TYPE_P(stmt->param_bind[i].zv) != IS_LONG) {
					zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;

					convert_to_double_ex(&tmp_data);
					if (Z_DVAL_P(tmp_data) > LONG_MAX || Z_DVAL_P(tmp_data) < LONG_MIN) {
						convert_to_string_ex(&tmp_data);
						current_type = MYSQL_TYPE_VAR_STRING;
						/*
						  don't change stmt->param_bind[i].type to MYSQL_TYPE_VAR_STRING
						  we force convert_to_long_ex in all cases, thus the type will be right in the next switch.
						  if the type is however not long, then we will do a goto in the next switch.
						  We want to preserve the original bind type given by the user. Thus, we do these hacks.
						*/
					} else {
						convert_to_long_ex(&tmp_data);
					}
				}
			}
			int2store(*p, current_type);
			*p+= 2;
		}
	}
	stmt->send_types_to_server = resend_types_next_time;

/* 2. Store data */
	/* 2.1 Calculate how much space we need */
	for (i = 0; i < stmt->param_count; i++) {
		unsigned int j;
		zval *the_var = stmt->param_bind[i].zv;

		if (!the_var || (stmt->param_bind[i].type != MYSQL_TYPE_LONG_BLOB && Z_TYPE_P(the_var) == IS_NULL)) {
			continue;
		}
		for (j = i + 1; j < stmt->param_count; j++) {
			if (stmt->param_bind[j].zv == the_var) {
				/* Double binding of the same zval, make a copy */
				if (!copies || !copies[i]) {
					if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) {
						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 || !copies[i]) {
						if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) {
							SET_OOM_ERROR(stmt->error_info);
							goto end;
						}
					}
				}
				break;
			case MYSQL_TYPE_LONGLONG:
				{
					zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
					if (Z_TYPE_P(tmp_data) == IS_STRING) {
						goto use_string;
					}
					convert_to_long_ex(&tmp_data);
				}
				data_size += 8;
				break;
			case MYSQL_TYPE_LONG:
				{
					zval *tmp_data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
					if (Z_TYPE_P(tmp_data) == IS_STRING) {
						goto use_string;
					}
					convert_to_long_ex(&tmp_data);
				}
				data_size += 4;
				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 MYSQLND_UNICODE
				if (Z_TYPE_P(the_var) != IS_STRING || Z_TYPE_P(the_var) == IS_UNICODE)
#else
				if (Z_TYPE_P(the_var) != IS_STRING)
#endif
				{
					if (!copies || !copies[i]) {
						if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) {
							SET_OOM_ERROR(stmt->error_info);
							goto end;
						}
					}
					the_var = copies[i];
#if MYSQLND_UNICODE
					if (Z_TYPE_P(the_var) == IS_UNICODE) {
						zval_unicode_to_string_ex(the_var, UG(utf8_conv) TSRMLS_CC);
					}
#endif
				}
				convert_to_string_ex(&the_var);
				data_size += Z_STRLEN_P(the_var);
				break;
		}
	}

	/* 2.2 Enlarge the buffer, if needed */
	left = (*buf_len - (*p - *buf));
	if (left < data_size) {
		unsigned int offset = *p - *buf;
		zend_uchar *tmp_buf;
		*buf_len = offset + data_size + 10; /* Allocate + 10 for safety */
		tmp_buf = mnd_emalloc(*buf_len);
		if (!tmp_buf) {
			SET_OOM_ERROR(stmt->error_info);
			goto end;
		}
		memcpy(tmp_buf, *buf, offset);
		/*
		  When too many columns the buffer provided to the function might not be sufficient.
		  In this case new buffer has been allocated above. When we allocate a buffer and then
		  allocate a bigger one here, we should free the first one.
		*/
		if (*buf != provided_buffer) {
			mnd_efree(*buf);
		}
		*buf = tmp_buf;
		/* Update our pos pointer */
		*p = *buf + offset;
	}

	/* 2.3 Store the actual data */
	for (i = 0; i < stmt->param_count; i++) {
		zval *data = (copies && copies[i])? copies[i]: stmt->param_bind[i].zv;
		/* Handle long data */
		if (stmt->param_bind[i].zv && Z_TYPE_P(data) == IS_NULL) {
			(*buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
		} else {
			switch (stmt->param_bind[i].type) {
				case MYSQL_TYPE_DOUBLE:
					convert_to_double_ex(&data);
					float8store(*p, Z_DVAL_P(data));
					(*p) += 8;
					break;
				case MYSQL_TYPE_LONGLONG:
					if (Z_TYPE_P(data) == IS_STRING) {
						goto send_string;
					}
					/* data has alreade been converted to long */
					int8store(*p, Z_LVAL_P(data));
					(*p) += 8;
					break;
				case MYSQL_TYPE_LONG:
					if (Z_TYPE_P(data) == IS_STRING) {
						goto send_string;
					}
					/* data has alreade been converted to long */
					int4store(*p, Z_LVAL_P(data));
					(*p) += 4;
					break;
				case MYSQL_TYPE_LONG_BLOB:
					if (stmt->param_bind[i].flags & MYSQLND_PARAM_BIND_BLOB_USED) {
						stmt->param_bind[i].flags &= ~MYSQLND_PARAM_BIND_BLOB_USED;
					} else {
						/* send_long_data() not called, send empty string */
						*p = php_mysqlnd_net_store_length(*p, 0);
					}
					break;
				case MYSQL_TYPE_VAR_STRING:
send_string:
					{
						unsigned int len = Z_STRLEN_P(data);
						/* to is after p. The latter hasn't been moved */
						*p = php_mysqlnd_net_store_length(*p, len);
						memcpy(*p, Z_STRVAL_P(data), len);
						(*p) += len;
					}
					break;
				default:
					/* Won't happen, but set to NULL */
					(*buf + null_byte_offset)[i/8] |= (zend_uchar) (1 << (i & 7));
					break;
			}
		}
	}
	ret = PASS;
end:
	if (copies) {
		for (i = 0; i < stmt->param_count; i++) {
			if (copies[i]) {
				zval_ptr_dtor(&copies[i]);
			}
		}
		mnd_efree(copies);
	}

	DBG_INF_FMT("ret=%s", ret == PASS? "PASS":"******");
	DBG_RETURN(ret);
}