Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t1UJM-00GXIb-QX for pgsql-bugs@arkaria.postgresql.org; Thu, 17 Oct 2024 17:29:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1t1UJL-007dC7-2b for pgsql-bugs@arkaria.postgresql.org; Thu, 17 Oct 2024 17:29:19 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t1UJK-007dBy-Pt for pgsql-bugs@lists.postgresql.org; Thu, 17 Oct 2024 17:29:19 +0000 Received: from momjian.us ([72.94.173.45]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t1UJB-001Zpd-Rn for pgsql-bugs@lists.postgresql.org; Thu, 17 Oct 2024 17:29:15 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=momjian.us; s=2024011501; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID: Subject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description; bh=nAXGTWYkGnF1woM1i4Wfo0NIRsvL7HVUES4j0i5xjFI=; b=WAOVo Yt91z2WjWrInvVsWbjBQoJuFR76MkIMKREous7uZhfm8F78jou4owb0iu6Xa3JONRLhKdh/p/Yez4 kGcaLTnHw8cZnLTx5X8lNue1SX+zDjSbjX4Ch+msPRegtQe+8MHYuF0XXtP2BqvLe+ZBD5V5+dDHe lDYL28lnmUf3HZcXD984HSLo/xjMBYtpVZE/fTFYBxXamiWgQoX9ee3+zZNOmanY+8FqujVi5GuFE OKt6lWCqXb1iZ6kfT4zwiAvKpyu98VfdFQRXSoiYCo5h3LVL438mKUVtmJRrbHwGJ2PWBMapPysgp 5A5Pr1JnEpwlmPw0lUcPgdTdz+8bw==; Received: from bruce by momjian.us with local (Exim 4.96) (envelope-from ) id 1t1UJ5-0027Gn-1w; Thu, 17 Oct 2024 13:29:03 -0400 Date: Thu, 17 Oct 2024 13:29:03 -0400 From: Bruce Momjian To: Michael Paquier Cc: p.nekrasov@fobos-nt.ru, pgsql-bugs@lists.postgresql.org Subject: Re: BUG #18614: [ECPG] out of bound in DecodeDateTime Message-ID: References: <18614-6bbe00117352309e@postgresql.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="MFFEuaY10y8MCOfD" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --MFFEuaY10y8MCOfD Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Wed, Oct 16, 2024 at 09:18:10AM +0900, Michael Paquier wrote: > On Mon, Oct 14, 2024 at 05:52:59PM -0400, Bruce Momjian wrote: > > /* > > - * check for valid day of month, now that we know for sure the month > > + * check for valid day of month and month, now that we know for sure the month > > * and year... > > */ > > - if (tm->tm_mday < 1 || tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]) > > + if (tm->tm_mon < 1 || tm->tm_mday < 1 || tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]) > > return -1; > > I would suggest adding a test. This is tricky enough and really easy > to miss, even if ECPG is not that touched these days. > > There are a lot of callers of PGTYPEStimestamp_from_asc() in > dt_test.pgc that do sanity checks on such inputs. Added in the attached patch. Is the output correct? -- Bruce Momjian https://momjian.us EDB https://enterprisedb.com When a patient asks the doctor, "Am I going to die?", he means "Am I going to die soon?" --MFFEuaY10y8MCOfD Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="ecpg.diff" diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.c index 0d63fe52c5b..51e35fee83b 100644 --- a/src/interfaces/ecpg/pgtypeslib/dt_common.c +++ b/src/interfaces/ecpg/pgtypeslib/dt_common.c @@ -2327,10 +2327,10 @@ DecodeDateTime(char **field, int *ftype, int nf, return ((fmask & DTK_TIME_M) == DTK_TIME_M) ? 1 : -1; /* - * check for valid day of month, now that we know for sure the month - * and year... + * check for valid day of month and month, now that we know for + * sure the month and year... */ - if (tm->tm_mday < 1 || tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]) + if (tm->tm_mon < 1 || tm->tm_mday < 1 || tm->tm_mday > day_tab[isleap(tm->tm_year)][tm->tm_mon - 1]) return -1; /* diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c index ee867b6dd86..1c4af713677 100644 --- a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c +++ b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.c @@ -267,6 +267,11 @@ if (sqlca.sqlcode < 0) sqlprint ( );} printf("timestamp_to_asc3: %s\n", text); PGTYPESchar_free(text); + ts1 = PGTYPEStimestamp_from_asc("AM95000062", NULL); + text = PGTYPEStimestamp_to_asc(ts1); + printf("timestamp_to_asc4: %s\n", text); + PGTYPESchar_free(text); + /* abc-03:10:35-def-02/11/94-gh */ /* 12345678901234567890123456789 */ @@ -453,16 +458,16 @@ if (sqlca.sqlcode < 0) sqlprint ( );} free(out); { ECPGtrans(__LINE__, NULL, "rollback"); -#line 381 "dt_test.pgc" +#line 386 "dt_test.pgc" if (sqlca.sqlcode < 0) sqlprint ( );} -#line 381 "dt_test.pgc" +#line 386 "dt_test.pgc" { ECPGdisconnect(__LINE__, "CURRENT"); -#line 382 "dt_test.pgc" +#line 387 "dt_test.pgc" if (sqlca.sqlcode < 0) sqlprint ( );} -#line 382 "dt_test.pgc" +#line 387 "dt_test.pgc" return 0; diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stderr b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stderr index 6e9ed3d3dba..0b81d27f5ba 100644 --- a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stderr +++ b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stderr @@ -42,7 +42,7 @@ [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_get_data on line 38: RESULT: 2000-07-12 17:34:29 offset: -1; array: no [NO_PID]: sqlca: code: 0, state: 00000 -[NO_PID]: ECPGtrans on line 381: action "rollback"; connection "ecpg1_regression" +[NO_PID]: ECPGtrans on line 386: action "rollback"; connection "ecpg1_regression" [NO_PID]: sqlca: code: 0, state: 00000 [NO_PID]: ecpg_finish: connection ecpg1_regression closed [NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stdout b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stdout index 4b582fd7a28..ae07f6c591f 100644 --- a/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stdout +++ b/src/interfaces/ecpg/test/expected/pgtypeslib-dt_test.stdout @@ -21,6 +21,7 @@ date_defmt_asc12: 0095-12-25 timestamp_to_asc1: 1996-02-29 00:00:00 timestamp_to_asc2: 1994-02-11 03:10:35 timestamp_to_asc3: 2000-01-01 00:00:00 +timestamp_to_asc4: 2000-01-01 00:00:00 timestamp_fmt_asc: 0: abc-00:00:00-def-01/01/00-ghi% timestamp_defmt_asc(This is a 4/12/80 3-39l12test, This is a %m/%d/%y %H-%Ml%Stest) = 1980-04-12 03:39:12, error: 0 timestamp_defmt_asc(Tue Jul 22 17:28:44 +0200 2003, %a %b %d %H:%M:%S %z %Y) = 2003-07-22 15:28:44, error: 0 diff --git a/src/interfaces/ecpg/test/pgtypeslib/dt_test.pgc b/src/interfaces/ecpg/test/pgtypeslib/dt_test.pgc index f81a3926655..7f434e2b6b8 100644 --- a/src/interfaces/ecpg/test/pgtypeslib/dt_test.pgc +++ b/src/interfaces/ecpg/test/pgtypeslib/dt_test.pgc @@ -193,6 +193,11 @@ main(void) printf("timestamp_to_asc3: %s\n", text); PGTYPESchar_free(text); + ts1 = PGTYPEStimestamp_from_asc("AM95000062", NULL); + text = PGTYPEStimestamp_to_asc(ts1); + printf("timestamp_to_asc4: %s\n", text); + PGTYPESchar_free(text); + /* abc-03:10:35-def-02/11/94-gh */ /* 12345678901234567890123456789 */ --MFFEuaY10y8MCOfD--