From 830affeffa5d4a56bc137260d6b8aa2fc76471c3 Mon Sep 17 00:00:00 2001 From: Kenichi Ishigaki Date: Tue, 10 Jan 2012 17:16:25 +0000 Subject: [PATCH] resolved #73787 --- Changes | 4 +++- dbdimp.c | 10 ++++------ t/rt_73787_exponential_buffer_overflow.t | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 t/rt_73787_exponential_buffer_overflow.t diff --git a/Changes b/Changes index 1d439f3..05aec7a 100644 --- a/Changes +++ b/Changes @@ -1,9 +1,11 @@ Changes for Perl extension DBD-SQLite -1.36_01 Tue 29 Nov 2011 +1.36_01 to be released - Enabled SQLITE_ENABLE_FTS4 - Enabled SQLITE_ENABLE_STAT3 - Resolved #73159: FTS tokenizer segfault (ISHIGAKI) + - Resolved #73787: sqlite_see_if_its_a_number causes a buffer + overflow (ISHIGAKI) 1.35 Tue 29 Nov 2011 - Updated to SQLite 3.7.9 (ISHIGAKI) diff --git a/dbdimp.c b/dbdimp.c index 56ea851..2683f54 100644 --- a/dbdimp.c +++ b/dbdimp.c @@ -166,7 +166,7 @@ sqlite_is_number(pTHX_ const char *v, bool strict) int neg; int digit = 0; int precision = 0; - char str[30], format[10]; + char format[10]; if (!strict) { while (*z == ' ') { z++; v++; } @@ -192,7 +192,7 @@ sqlite_is_number(pTHX_ const char *v, bool strict) } #else if (digit > 11) return 0; /* too large for i32 */ - if (digit == 10) { + if (digit == 11) { int c; char tmp[14]; strncpy(tmp, v, z - v + 1); @@ -215,12 +215,10 @@ sqlite_is_number(pTHX_ const char *v, bool strict) while (isdigit(*z)) { z++; } } - sprintf(str, "%i", atoi(v)); - if (strEQ(str, v)) return 1; + if (strEQ(form("%i", atoi(v)), v)) return 1; if (precision) { sprintf(format, "%%.%df", precision); - sprintf(str, format, atof(v)); - if (strEQ(str, v)) return 2; + if (strEQ(form(format, atof(v)), v)) return 2; } return 0; } diff --git a/t/rt_73787_exponential_buffer_overflow.t b/t/rt_73787_exponential_buffer_overflow.t new file mode 100644 index 0000000..6115864 --- /dev/null +++ b/t/rt_73787_exponential_buffer_overflow.t @@ -0,0 +1,23 @@ +#!/usr/bin/perl + +use strict; +BEGIN { + $| = 1; + $^W = 1; +} + +use t::lib::Test qw/connect_ok/; +use Test::More tests => 6; +use Test::NoWarnings; + +my $dbh = connect_ok(sqlite_see_if_its_a_number => 1); +$dbh->do('create table foo (id integer primary key, exp)'); +my $ct = 0; +for my $value (qw/2e100 10.04e100/) { + eval { + $dbh->do('insert into foo values (?, ?)', undef, $ct++, $value); + my $got = $dbh->selectrow_arrayref('select * from foo where exp = ?', undef, $value); + is $value => $got->[1], "got ".$got->[0]; + }; + ok !$@, "and without errors"; +}