[svn:DBD-Pg] r12741 - in DBD-Pg/trunk: . t

[email protected]
Newsgroups gmane.comp.db.postgresql.dbdpg.cvs
Message-ID <[email protected]>
Author: turnstep
Date: Mon May  4 13:44:30 2009
New Revision: 12741

Modified:
   DBD-Pg/trunk/quote.c
   DBD-Pg/trunk/quote.h
   DBD-Pg/trunk/t/12placeholders.t
   DBD-Pg/trunk/types.c

Log:
Quick commit of work in progress to fix quoting problem.


Modified: DBD-Pg/trunk/quote.c
==============================================================================
--- DBD-Pg/trunk/quote.c	(original)
+++ DBD-Pg/trunk/quote.c	Mon May  4 13:44:30 2009
@@ -260,29 +260,75 @@
 	return result;
 }
 
+char * quote_int(const char *string, STRLEN len, STRLEN *retlen, int estring)
+{
+	dTHX;
+	char * result;
+
+	New(0, result, len+1, char);
+	strcpy(result,string);
+	*retlen = len;
 
+	while (len > 0 && *string != '\0') {
+		len--;
+		if (isdigit(*string) || ' ' == *string || '+' == *string || '-' == *string) {
+			*string++;
+			continue;			
+		}
+		croak("Invalid integer");
+	}
 
-char * quote_integer(const char *value, STRLEN len, STRLEN *retlen, int estring) 
+	return result;
+}
+
+
+char * quote_float(const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
 	dTHX;
-	char *result;
-	STRLEN max_len=6;
-        const int intval = *((const int*)value);
-	len = 0;
-
-	New(0, result, max_len, char);
-	
-	if (0 == intval)
-		strncpy(result,"FALSE\0",6);
-	else if (1 == intval)
-		strncpy(result,"TRUE\0",5);
-	
-	*retlen = strlen(result);
-	assert(*retlen+1 <= max_len);
+	char * result;
+	double val;
+
+	/*
+	  We do minimal checking here, and let Postgres do the heavy lifting 
+	  Out job is to simply filter out bad characters
+	*/
+
+	while (*string != '\0' && isspace((unsigned char) *string))
+		*string++;
+
+	errno = 0;
+	val = strtod(string, &result);
+
+	if (result == string || errno != 0) {
+		/* Allow exactly three strings, otherwise bail */
+		if (0 != strncasecmp(string, "NaN", 3)
+			&& 0 != strncasecmp(string, "Infinity", 8)
+			&& 0 != strncasecmp(string, "-Infinity", 9)
+			) {
+			croak("Invalid number");
+		}
+	}
+
+	New(0, result, len+1, char);
+	strcpy(result,string);
+	*retlen = len;
 
 	return result;
 }
 
+char * quote_name(const char *string, STRLEN len, STRLEN *retlen, int estring)
+{
+	dTHX;
+	char * result;
+
+	croak ("Not handled yet");
+
+	New(0, result, len+1, char);
+	strcpy(result,string);
+	*retlen = len;
+
+	return result;
+}
 
 
 void dequote_char(const char *string, STRLEN *retlen, int estring)

Modified: DBD-Pg/trunk/quote.h
==============================================================================
--- DBD-Pg/trunk/quote.h	(original)
+++ DBD-Pg/trunk/quote.h	Mon May  4 13:44:30 2009
@@ -5,6 +5,9 @@
 char * quote_sql_binary(char *string, STRLEN len, STRLEN *retlen, int estring);
 char * quote_bool(const char *string, STRLEN len, STRLEN *retlen, int estring);
 char * quote_integer(const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_int(const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_float(const char *string, STRLEN len, STRLEN *retlen, int estring);
+char * quote_name(const char *string, STRLEN len, STRLEN *retlen, int estring);
 char * quote_geom(const char *string, STRLEN len, STRLEN *retlen, int estring);
 char * quote_path(const char *string, STRLEN len, STRLEN *retlen, int estring);
 char * quote_circle(const char *string, STRLEN len, STRLEN *retlen, int estring);

Modified: DBD-Pg/trunk/t/12placeholders.t
==============================================================================
--- DBD-Pg/trunk/t/12placeholders.t	(original)
+++ DBD-Pg/trunk/t/12placeholders.t	Mon May  4 13:44:30 2009
@@ -7,6 +7,7 @@
 use warnings;
 use Test::More;
 use lib 't','.';
+use DBI qw/:sql_types/;
 require 'dbdpg_test_setup.pl';
 select(($|=1,select(STDERR),$|=1)[1]);
 
@@ -308,6 +309,38 @@
 	is ($@, q{}, $t);
 }
 
+my $val;
+$val = $dbh->quote('123', SQL_INTEGER);
+is ($val,123, 'GO?');
+
+eval {
+	$val = $dbh->quote('123abc', SQL_INTEGER);
+};
+like ($@, qr{Invalid integer}, 'Invalid integer fails to pass through');
+
+
+$val = $dbh->quote('123', SQL_INTEGER);
+is ($val,123, 'GO?');
+
+eval {
+	$val = $dbh->quote('123abc', SQL_FLOAT);
+};
+like ($@, qr{Invalid integer}, 'Invalid integer fails to pass through');
+
+exit;
+
+$dbh->rollback();
+## Test placeholerds plus binding
+$t='Bound placeholders enforce data types when not using server side prepares';
+$dbh->trace(0);
+$dbh->{pg_server_prepare} = 0;
+$sth = $dbh->prepare("SELECT (1+?+?)::integer");
+$sth->bind_param(1, 1, SQL_INTEGER);
+eval {
+	$sth->execute('10foo',20);
+};
+like ($@, qr{Invalid integer}, 'Invalid integer test 2');
+
 ## Begin custom type testing
 
 $dbh->rollback();

Modified: DBD-Pg/trunk/types.c
==============================================================================
--- DBD-Pg/trunk/types.c	(original)
+++ DBD-Pg/trunk/types.c	Mon May  4 13:44:30 2009
@@ -94,14 +94,14 @@
  {PG_CIRCLE            ,"circle"           ,1,',',"circle_out"      ,quote_circle,dequote_string,{0},0},
  {PG_CSTRING           ,"cstring"          ,1,',',"cstring_out"     ,quote_string,dequote_string,{0},0},
  {PG_DATE              ,"date"             ,1,',',"date_out"        ,quote_string,dequote_string,{SQL_TYPE_DATE},0},
- {PG_FLOAT4            ,"float4"           ,1,',',"float4out"       ,null_quote  ,null_dequote  ,{0},2},
- {PG_FLOAT8            ,"float8"           ,1,',',"float8out"       ,null_quote  ,null_dequote  ,{SQL_FLOAT},2},
+ {PG_FLOAT4            ,"float4"           ,1,',',"float4out"       ,quote_float ,null_dequote  ,{0},2},
+ {PG_FLOAT8            ,"float8"           ,1,',',"float8out"       ,quote_float ,null_dequote  ,{SQL_FLOAT},2},
  {PG_GTSVECTOR         ,"gtsvector"        ,1,',',"gtsvectorout"    ,quote_string,dequote_string,{0},0},
  {PG_INET              ,"inet"             ,1,',',"inet_out"        ,quote_string,dequote_string,{0},0},
- {PG_INT2              ,"int2"             ,1,',',"int2out"         ,null_quote  ,null_dequote  ,{SQL_SMALLINT},1},
+ {PG_INT2              ,"int2"             ,1,',',"int2out"         ,quote_int   ,null_dequote  ,{SQL_SMALLINT},1},
  {PG_INT2VECTOR        ,"int2vector"       ,1,',',"int2vectorout"   ,quote_string,dequote_string,{0},0},
- {PG_INT4              ,"int4"             ,1,',',"int4out"         ,null_quote  ,null_dequote  ,{SQL_INTEGER},1},
- {PG_INT8              ,"int8"             ,1,',',"int8out"         ,null_quote  ,null_dequote  ,{SQL_BIGINT},0},
+ {PG_INT4              ,"int4"             ,1,',',"int4out"         ,quote_int   ,null_dequote  ,{SQL_INTEGER},1},
+ {PG_INT8              ,"int8"             ,1,',',"int8out"         ,quote_int   ,null_dequote  ,{SQL_BIGINT},0},
  {PG_INTERNAL          ,"internal"         ,1,',',"internal_out"    ,quote_string,dequote_string,{0},0},
  {PG_INTERVAL          ,"interval"         ,1,',',"interval_out"    ,quote_string,dequote_string,{0},0},
  {PG_LANGUAGE_HANDLER  ,"language_handler" ,1,',',"language_handler_out",quote_string,dequote_string,{0},0},
@@ -109,9 +109,9 @@
  {PG_LSEG              ,"lseg"             ,1,',',"lseg_out"        ,quote_geom  ,dequote_string,{0},0},
  {PG_MACADDR           ,"macaddr"          ,1,',',"macaddr_out"     ,quote_string,dequote_string,{0},0},
  {PG_MONEY             ,"money"            ,1,',',"cash_out"        ,quote_string,dequote_string,{0},0},
- {PG_NAME              ,"name"             ,1,',',"nameout"         ,null_quote  ,null_dequote  ,{SQL_VARCHAR},0},
- {PG_NUMERIC           ,"numeric"          ,1,',',"numeric_out"     ,null_quote  ,null_dequote  ,{SQL_DECIMAL},2},
- {PG_OID               ,"oid"              ,1,',',"oidout"          ,null_quote  ,null_dequote  ,{0},1},
+ {PG_NAME              ,"name"             ,1,',',"nameout"         ,quote_name  ,null_dequote  ,{SQL_VARCHAR},0},
+ {PG_NUMERIC           ,"numeric"          ,1,',',"numeric_out"     ,quote_float ,null_dequote  ,{SQL_DECIMAL},2},
+ {PG_OID               ,"oid"              ,1,',',"oidout"          ,quote_int   ,null_dequote  ,{0},1},
  {PG_OIDVECTOR         ,"oidvector"        ,1,',',"oidvectorout"    ,quote_string,dequote_string,{0},0},
  {PG_OPAQUE            ,"opaque"           ,1,',',"opaque_out"      ,quote_string,dequote_string,{0},0},
  {PG_PATH              ,"path"             ,1,',',"path_out"        ,quote_path  ,dequote_string,{0},0},
@@ -303,16 +303,16 @@
  {SQL_VARBINARY,"SQL_VARBINARY",1,',', "none", quote_bytea, dequote_bytea, {PG_BYTEA}, 0},
  {SQL_CHAR,"SQL_CHAR",1,',', "none", quote_string, dequote_char, {PG_CHAR}, 0},
  {SQL_TYPE_DATE,"SQL_TYPE_DATE",1,',', "none", quote_string, dequote_string, {PG_DATE}, 0},
- {SQL_FLOAT,"SQL_FLOAT",1,',', "none", null_quote, null_dequote, {PG_FLOAT8}, 2},
- {SQL_DOUBLE,"SQL_DOUBLE",1,',', "none", null_quote, null_dequote, {PG_FLOAT8}, 2},
- {SQL_NUMERIC,"SQL_NUMERIC",1,',', "none", null_quote, null_dequote, {PG_FLOAT8}, 2},
- {SQL_REAL,"SQL_REAL",1,',', "none", null_quote, null_dequote, {PG_FLOAT8}, 2},
- {SQL_SMALLINT,"SQL_SMALLINT",1,',', "none", null_quote, null_dequote, {PG_INT2}, 1},
- {SQL_TINYINT,"SQL_TINYINT",1,',', "none", null_quote, null_dequote, {PG_INT2}, 1},
- {SQL_INTEGER,"SQL_INTEGER",1,',', "none", null_quote, null_dequote, {PG_INT4}, 1},
- {SQL_BIGINT,"SQL_BIGINT",1,',', "none", null_quote, null_dequote, {PG_INT8}, 0},
- {SQL_VARCHAR,"SQL_VARCHAR",1,',', "none", null_quote, null_dequote, {PG_NAME}, 0},
- {SQL_DECIMAL,"SQL_DECIMAL",1,',', "none", null_quote, null_dequote, {PG_NUMERIC}, 2},
+ {SQL_FLOAT,"SQL_FLOAT",1,',', "none", quote_float, null_dequote, {PG_FLOAT8}, 2},
+ {SQL_DOUBLE,"SQL_DOUBLE",1,',', "none", quote_float, null_dequote, {PG_FLOAT8}, 2},
+ {SQL_NUMERIC,"SQL_NUMERIC",1,',', "none", quote_float, null_dequote, {PG_FLOAT8}, 2},
+ {SQL_REAL,"SQL_REAL",1,',', "none", quote_float, null_dequote, {PG_FLOAT8}, 2},
+ {SQL_SMALLINT,"SQL_SMALLINT",1,',', "none", quote_int, null_dequote, {PG_INT2}, 1},
+ {SQL_TINYINT,"SQL_TINYINT",1,',', "none", quote_int, null_dequote, {PG_INT2}, 1},
+ {SQL_INTEGER,"SQL_INTEGER",1,',', "none", quote_int, null_dequote, {PG_INT4}, 1},
+ {SQL_BIGINT,"SQL_BIGINT",1,',', "none", quote_int, null_dequote, {PG_INT8}, 0},
+ {SQL_VARCHAR,"SQL_VARCHAR",1,',', "none", quote_name, null_dequote, {PG_NAME}, 0},
+ {SQL_DECIMAL,"SQL_DECIMAL",1,',', "none", quote_float, null_dequote, {PG_NUMERIC}, 2},
  {SQL_LONGVARCHAR,"SQL_LONGVARCHAR",1,',', "none", quote_string, dequote_string, {PG_TEXT}, 0},
  {SQL_TYPE_TIME,"SQL_TYPE_TIME",1,',', "none", quote_string, dequote_string, {PG_TIME}, 0},
  {SQL_TIMESTAMP,"SQL_TIMESTAMP",1,',', "none", quote_string, dequote_string, {PG_TIMESTAMP}, 0},
@@ -722,14 +722,14 @@
 cid      quote_string  dequote_string  0                         0  0
 
 ## Things that get no quoting at all (e.g. numbers)
-int2     null_quote    null_dequote    SQL_SMALLINT|SQL_TINYINT  1  1
-int4     null_quote    null_dequote    SQL_INTEGER               1  1
-int8     null_quote    null_dequote    SQL_BIGINT                1  0
-float4   null_quote    null_dequote    0                         1  2
-float8   null_quote    null_dequote    SQL_FLOAT|SQL_DOUBLE|SQL_NUMERIC|SQL_REAL 1  2
-numeric  null_quote    null_dequote    SQL_DECIMAL               1  2
-oid      null_quote    null_dequote    0                         0  1
-name     null_quote    null_dequote    SQL_VARCHAR               0  0 ## XXX Wrong
+int2     quote_int     null_dequote    SQL_SMALLINT|SQL_TINYINT  1  1
+int4     quote_int     null_dequote    SQL_INTEGER               1  1
+int8     quote_int     null_dequote    SQL_BIGINT                1  0
+float4   quote_float   null_dequote    0                         1  2
+float8   quote_float   null_dequote    SQL_FLOAT|SQL_DOUBLE|SQL_NUMERIC|SQL_REAL 1  2
+numeric  quote_float   null_dequote    SQL_DECIMAL               1  2
+oid      quote_int     null_dequote    0                         0  1
+name     quote_name    null_dequote    SQL_VARCHAR               0  0 ## XXX Wrong
 
 ## Boolean
 bool     quote_bool    dequote_bool    SQL_BOOLEAN               1  3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.