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

[email protected]
Newsgroups gmane.comp.db.postgresql.dbdpg.cvs
Message-ID <[email protected]>
Author: turnstep
Date: Mon Jul 20 09:13:03 2009
New Revision: 13089

Modified:
   DBD-Pg/trunk/Changes
   DBD-Pg/trunk/quote.c
   DBD-Pg/trunk/t/12placeholders.t
   DBD-Pg/trunk/t/dbdpg_test_setup.pl

Log:
Fix up geometric type quoting, and make tests for same.
Per bug 41565


Modified: DBD-Pg/trunk/Changes
==============================================================================
--- DBD-Pg/trunk/Changes	(original)
+++ DBD-Pg/trunk/Changes	Mon Jul 20 09:13:03 2009
@@ -3,6 +3,7 @@
 2.13.1_4
 
   - Make quoting of int, floats, and names much safer. (CPAN bug #41565) [GSM]
+  - Make quoting of geometric types respect all valid chars (CPAN bug #41565) [GSM]
   - Return ints and bools-cast-to-number from the db as true Perlish numbers.
     (CPAN bug #47619) [GSM]
   - Fix backslash quoting of arrays (CPAN bug #46732) [GSM]

Modified: DBD-Pg/trunk/quote.c
==============================================================================
--- DBD-Pg/trunk/quote.c	(original)
+++ DBD-Pg/trunk/quote.c	Mon Jul 20 09:13:03 2009
@@ -100,17 +100,23 @@
 }
 
 
+/* Quote a geometric constant. */
+/* Note: we only verify correct characters here, not for 100% valid input */
+/* Covers: points, lines, lsegs, boxes, polygons */
 char * quote_geom(const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
 	dTHX;
 	char * result;
-        const char *tmp;
+	const char *tmp;
 
 	len = 0; /* stops compiler warnings. Remove entirely someday */
 	tmp = string;
 	(*retlen) = 2;
+
 	while (*string != '\0') {
 		if (*string !=9 && *string != 32 && *string != '(' && *string != ')'
+			&& *string != '-' && *string != '+' && *string != '.'
+			&& *string != 'e' && *string != 'E'
 			&& *string != ',' && (*string < '0' || *string > '9'))
 			croak("Invalid input for geometric type");
 		(*retlen)++;
@@ -128,6 +134,7 @@
 	return result - (*retlen);
 }
 
+/* Same as quote_geom, but also allows square brackets */
 char * quote_path(const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
 	dTHX;
@@ -138,9 +145,11 @@
 	(*retlen) = 2;
 	while (*string != '\0') {
 		if (*string !=9 && *string != 32 && *string != '(' && *string != ')'
-			&& *string != ',' && *string != '[' && *string != ']'
-			&& (*string < '0' || *string > '9'))
-				croak("Invalid input for geometric path type");
+			&& *string != '-' && *string != '+' && *string != '.'
+			&& *string != 'e' && *string != 'E'
+			&& *string != '[' && *string != ']'
+			&& *string != ',' && (*string < '0' || *string > '9'))
+			croak("Invalid input for path type");
 		(*retlen)++;
 		string++;
 	}
@@ -156,6 +165,7 @@
 	return result - (*retlen);
 }
 
+/* Same as quote_geom, but also allows less than / greater than signs */
 char * quote_circle(const char *string, STRLEN len, STRLEN *retlen, int estring)
 {
 	dTHX;
@@ -164,11 +174,14 @@
 
 	len = 0; /* stops compiler warnings. Remove entirely someday */
 	(*retlen) = 2;
+
 	while (*string != '\0') {
 		if (*string !=9 && *string != 32 && *string != '(' && *string != ')'
-			&& *string != ',' && *string != '<' && *string != '>'
-			&& (*string < '0' || *string > '9'))
-				croak("Invalid input for geometric circle type");
+			&& *string != '-' && *string != '+' && *string != '.'
+			&& *string != 'e' && *string != 'E'
+			&& *string != '<' && *string != '>'
+			&& *string != ',' && (*string < '0' || *string > '9'))
+			croak("Invalid input for circle type");
 		(*retlen)++;
 		string++;
 	}

Modified: DBD-Pg/trunk/t/12placeholders.t
==============================================================================
--- DBD-Pg/trunk/t/12placeholders.t	(original)
+++ DBD-Pg/trunk/t/12placeholders.t	Mon Jul 20 09:13:03 2009
@@ -17,7 +17,7 @@
 if (! defined $dbh) {
 	plan skip_all => 'Connection to database failed, cannot continue testing';
 }
-plan tests => 129;
+plan tests => 213;
 
 my $t='Connect to database for placeholder testing';
 isnt ($dbh, undef, $t);
@@ -27,6 +27,8 @@
   $dbh->do('SET escape_string_warning = false');
 }
 
+my ($sth, $result, $SQL, $qresult);
+
 # Make sure that quoting works properly.
 $t='Quoting works properly';
 my $E = $pgversion >= 80100 ? q{E} : q{};
@@ -350,17 +352,11 @@
 }
 
 $prefix = 'Invalid float value fails when quoting with SQL_FLOAT';
-## This is temporary to help track down a failing test
-use Data::Dumper;
 for my $float ('3abc','123abc','','123e+04e+34','NaNum','-infinitee') {
 	$t = "$prefix (value=$float)";
 	$val = -1;
 	eval { $val = $dbh->quote($float, SQL_FLOAT); };
 	like ($@, qr{Invalid number}, $t);
-	diag Dumper $@;
-	my $foo = $@;
-	$foo =~ s/(.)/"$1(".ord($1).")"/ge;
-	diag $foo;
 	is ($val, -1, $t);
 }
 
@@ -394,6 +390,279 @@
 	is($got, $expected, $t);
 }
 
+## Test quoting of geometric types
+
+
+
+my @geotypes = qw/point line lseg box path polygon circle/;
+
+$dbh->do("SET search_path TO DEFAULT");
+eval { $dbh->do("DROP TABLE dbd_pg_test_geom"); }; $dbh->commit();
+
+$SQL = 'CREATE TABLE dbd_pg_test_geom (';
+for my $type (@geotypes) {
+	$SQL .= "x$type $type,";
+}
+$SQL =~ s/,$/)/;
+$dbh->do($SQL);
+$dbh->commit();
+
+my %typemap = (
+	point   => PG_POINT,
+	line    => PG_LINE,
+	lseg    => PG_LSEG,
+	box     => PG_BOX,
+	path    => PG_PATH,
+	polygon => PG_POLYGON,
+	circle  => PG_CIRCLE,
+);
+
+my $testdata = q{
+point datatype integers
+12,34
+'12,34'
+(12,34)
+
+point datatype floating point numbers
+1.34,667
+'1.34,667'
+(1.34,667)
+
+point datatype exponential numbers
+1e34,9E4
+'1e34,9E4'
+(1e+34,90000)
+
+point datatype plus and minus signs
+1e+34,-.45
+'1e+34,-.45'
+(1e+34,-0.45)
+
+point datatype invalid number
+123,abc
+ERROR: Invalid input for geometric type
+ERROR: any
+
+point datatype invalid format
+123
+'123'
+ERROR: any
+
+point datatype invalid format
+123,456,789
+'123,456,789'
+ERROR: any
+
+point datatype invalid format
+<(2,4),6>
+ERROR: Invalid input for geometric type
+ERROR: any
+
+point datatype invalid format
+[(1,2)]
+ERROR: Invalid input for geometric type
+ERROR: any
+
+line datatype integers
+12,34
+'12,34'
+ERROR: not yet implemented
+
+line datatype floating point numbers
+1.34,667
+'1.34,667'
+ERROR: not yet implemented
+
+line datatype exponential numbers
+1e34,9E4
+'1e34,9E4'
+ERROR: not yet implemented
+
+line datatype plus and minus signs
+1e+34,-.45
+'1e+34,-.45'
+ERROR: not yet implemented
+
+line datatype invalid number
+123,abc
+ERROR: Invalid input for geometric type
+ERROR: not yet implemented
+
+
+lseg datatype invalid format
+12,34
+'12,34'
+ERROR: any
+
+lseg datatype integers
+(12,34),(56,78)
+'(12,34),(56,78)'
+[(12,34),(56,78)]
+
+lseg datatype floating point and exponential numbers
+(1.2,3.4),(5e3,7E1)
+'(1.2,3.4),(5e3,7E1)'
+[(1.2,3.4),(5000,70)]
+
+
+box datatype invalid format
+12,34
+'12,34'
+ERROR: any
+
+box datatype integers
+(12,34),(56,78)
+'(12,34),(56,78)'
+(56,78),(12,34)
+
+box datatype floating point and exponential numbers
+(1.2,3.4),(5e3,7E1)
+'(1.2,3.4),(5e3,7E1)'
+(5000,70),(1.2,3.4)
+
+
+path datatype invalid format
+12,34
+'12,34'
+ERROR: any
+
+path datatype integers
+(12,34),(56,78)
+'(12,34),(56,78)'
+((12,34),(56,78))
+
+path datatype floating point and exponential numbers
+(1.2,3.4),(5e3,7E1)
+'(1.2,3.4),(5e3,7E1)'
+((1.2,3.4),(5000,70))
+
+path datatype alternate bracket format
+[(1.2,3.4),(5e3,7E1)]
+'[(1.2,3.4),(5e3,7E1)]'
+[(1.2,3.4),(5000,70)]
+
+path datatype many elements
+(1.2,3.4),(5,6),(7,8),(-9,10)
+'(1.2,3.4),(5,6),(7,8),(-9,10)'
+((1.2,3.4),(5,6),(7,8),(-9,10))
+
+path datatype fails with braces
+{(1,2),(3,4)}
+ERROR: Invalid input for path type
+ERROR: any
+
+
+polygon datatype invalid format
+12,34
+'12,34'
+ERROR: any
+
+polygon datatype integers
+(12,34),(56,78)
+'(12,34),(56,78)'
+((12,34),(56,78))
+
+polygon datatype floating point and exponential numbers
+(1.2,3.4),(5e3,7E1)
+'(1.2,3.4),(5e3,7E1)'
+((1.2,3.4),(5000,70))
+
+polygon datatype many elements
+(1.2,3.4),(5,6),(7,8),(-9,10)
+'(1.2,3.4),(5,6),(7,8),(-9,10)'
+((1.2,3.4),(5,6),(7,8),(-9,10))
+
+polygon datatype fails with brackets
+[(1,2),(3,4)]
+ERROR: Invalid input for geometric type
+ERROR: any
+
+
+
+circle datatype invalid format
+(12,34)
+'(12,34)'
+ERROR: any
+
+circle datatype integers
+<(12,34),5>
+'<(12,34),5>'
+<(12,34),5>
+
+circle datatype floating point and exponential numbers
+<(-1.2,2E2),3e3>
+'<(-1.2,2E2),3e3>'
+<(-1.2,200),3000>
+
+circle datatype fails with brackets
+[(1,2),(3,4)]
+ERROR: Invalid input for circle type
+ERROR: any
+
+};
+
+$testdata =~ s/^\s+//;
+my $curtype = '';
+for my $line (split /\n\n+/ => $testdata) {
+	my ($text,$input,$quoted,$rows) = split /\n/ => $line;
+	next if ! $text;
+	$t = "Geometric type test: $text";
+	(my $type) = ($text =~ m{(\w+)});
+	last if $type eq 'LAST';
+	if ($curtype ne $type) {
+		$curtype = $type;
+		eval { $dbh->do('DEALLOCATE geotest'); }; $dbh->commit();
+		$dbh->do(qq{PREPARE geotest($type) AS INSERT INTO dbd_pg_test_geom(x$type) VALUES (\$1)});
+		$sth = $dbh->prepare(qq{INSERT INTO dbd_pg_test_geom(x$type) VALUES (?)});
+		$sth->bind_param(1, '', {pg_type => $typemap{$type} });
+	}
+	$dbh->do('DELETE FROM dbd_pg_test_geom');
+	eval { $qresult = $dbh->quote($input, {pg_type => $typemap{$type}}); };
+	if ($@) {
+		if ($quoted !~ /ERROR: (.+)/) {
+			fail "$t error: $@";
+		}
+		else {
+			like ($@, qr{$1}, $t);
+		}
+	}
+	else {
+		is ($qresult, $quoted, $t);
+	}
+	$dbh->commit();
+
+	eval { $dbh->do("EXECUTE geotest('$input')"); };
+	if ($@) {
+		if ($rows !~ /ERROR: (.+)/) {
+			fail "$t error: $@";
+		}
+		else {
+			## Do any error for now: i18n worries
+			pass $t;
+		}
+	}
+	$dbh->commit();
+
+	eval { $sth->execute($input); };
+	if ($@) {
+		if ($rows !~ /ERROR: (.+)/) {
+			fail $t;
+		}
+		else {
+			## Do any error for now: i18n worries
+			pass $t;
+		}
+	}
+	$dbh->commit();
+
+	if ($rows !~ /ERROR/) {
+		$SQL = "SELECT x$type FROM dbd_pg_test_geom";
+		my $expected = [[$rows],[$rows]];
+		$result = $dbh->selectall_arrayref($SQL);
+		is_deeply($result, $expected, $t);
+	}
+}
+
 ## Begin custom type testing
 
 $dbh->rollback();

Modified: DBD-Pg/trunk/t/dbdpg_test_setup.pl
==============================================================================
--- DBD-Pg/trunk/t/dbdpg_test_setup.pl	(original)
+++ DBD-Pg/trunk/t/dbdpg_test_setup.pl	Mon Jul 20 09:13:03 2009
@@ -25,6 +25,7 @@
 	 'dbd_pg_test2',
 	 'dbd_pg_test1',
 	 'dbd_pg_test',
+	 'dbd_pg_test_geom',
 	 );
 
 my @sequences =
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.