BUG #16143: PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format specifier %b is used.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

BUG #16143: PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format specifier %b is used.

PG Doc comments form
The following bug has been logged on the website:

Bug reference:      16143
Logged by:          Paul Spencer
Email address:      [hidden email]
PostgreSQL version: 11.5
Operating system:   Redhat and Debian
Description:        

PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format
specifier %b is used.  The returned month is one greater then the expected
month.  If the expected month is “Dec”, the application may crash with a
segment fault.  The format specifier %B has a similar issue.

** Investigation Notes
- The month is increased by one at line 143 in timestamp2tm() defined in
timestamp.c 
https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/ecpg/pgtypeslib/timestamp.c;h=810dd06ee68b9e39bfbb8d1fb4b58b8205f24246;hb=HEAD
- The month number is converted to the abbreviation at line 337 in
dttofmtasc_replace() defined in timestamp.c  
https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/ecpg/pgtypeslib/timestamp.c;h=810dd06ee68b9e39bfbb8d1fb4b58b8205f24246;hb=HEAD
- Month abbreviations are defined at line 499 in dt_common.c 

https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/ecpg/pgtypeslib/dt_common.c;h=c1a3a3e2cb7e2d4f375a3b1a2e858f7347a867ea;hb=HEAD

***
* Use Case
***
pi@raspberrypi4:~/projects/postgres_month_date $ ./pg_month_date
PostgreSQL timestamp_fmt_asc()
PGTYPEStimestamp_to_asc returns 1999-01-08 04:06:06
Format string = %Y-%m-%d %H:%M:%S, Formated Date = 1999-01-08 04:06:06
Format string = %Y-%b-%d %H:%M:%S, Formated Date = 1999-Feb-08 04:06:06
pi@raspberrypi4:~/projects/postgres_month_date $

***
* Source code for the use case
***
/*
 * pg_month_date.c
 */
#include <stdio.h>
#include <string.h>

#include "pgtypes_timestamp.h"

int main(int argc, char **argv)
{
  char formatString[255] = "";
  char stringBuffer[255] = "";
  timestamp testTimestamp;
  char * endPtr = NULL;

  printf("%s\n","PostgreSQL timestamp_fmt_asc()");

  testTimestamp = PGTYPEStimestamp_from_asc("1999-01-08 04:06:06",
&endPtr);
  printf("PGTYPEStimestamp_to_asc returns %s\n",
PGTYPEStimestamp_to_asc(testTimestamp));
 
  strncpy(formatString, "%Y-%m-%d %H:%M:%S", sizeof(formatString));
  PGTYPEStimestamp_fmt_asc(&testTimestamp, stringBuffer,
sizeof(stringBuffer),formatString);
  printf( "Format string = %s, Formated Date = %s\n", formatString ,
stringBuffer);

  strncpy(formatString, "%Y-%b-%d %H:%M:%S", sizeof(formatString));
  PGTYPEStimestamp_fmt_asc(&testTimestamp, stringBuffer,
sizeof(stringBuffer),formatString);
  printf( "Format string = %s, Formated Date = %s\n", formatString ,
stringBuffer);
  return 0;
}


Paul Spencer

Reply | Threaded
Open this post in threaded view
|

Re: BUG #16143: PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format specifier %b is used.

Tomas Vondra-4
On Fri, Nov 29, 2019 at 07:40:37PM +0000, PG Bug reporting form wrote:

>The following bug has been logged on the website:
>
>Bug reference:      16143
>Logged by:          Paul Spencer
>Email address:      [hidden email]
>PostgreSQL version: 11.5
>Operating system:   Redhat and Debian
>Description:
>
>PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format
>specifier %b is used.  The returned month is one greater then the expected
>month.  If the expected month is “Dec”, the application may crash with a
>segment fault.  The format specifier %B has a similar issue.
>
>** Investigation Notes
>- The month is increased by one at line 143 in timestamp2tm() defined in
>timestamp.c 
https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/ecpg/pgtypeslib/timestamp.c;h=810dd06ee68b9e39bfbb8d1fb4b58b8205f24246;hb=HEAD
>- The month number is converted to the abbreviation at line 337 in
>dttofmtasc_replace() defined in timestamp.c  
https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/ecpg/pgtypeslib/timestamp.c;h=810dd06ee68b9e39bfbb8d1fb4b58b8205f24246;hb=HEAD
>- Month abbreviations are defined at line 499 in dt_common.c 

>https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/ecpg/pgtypeslib/dt_common.c;h=c1a3a3e2cb7e2d4f375a3b1a2e858f7347a867ea;hb=HEAD
>
Yeah, seems like a simple off-by-one mistake. Our tm->tm_mon is 1-based,
but dttofmtasc_replace uses it directly to access elements of arrays
with month names. Hence the "next" month is returned, and crash for the
last month (access out of bounds).

The attached patch should fix this, I believe - both for %b and %B.


regards

--
Tomas Vondra                  http://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

ecpg-month-index-fix.patch (866 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: BUG #16143: PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format specifier %b is used.

Tom Lane-2
In reply to this post by PG Doc comments form
PG Bug reporting form <[hidden email]> writes:
> PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format
> specifier %b is used.

Yeah, you're clearly right.  Defining struct pg_tm's tm_mon differently
from the common understanding of struct tm's tm_mon may not have been
the greatest idea we ever had :-(.  I dug through the uses of tm_mon in
the rest of ecpglib and didn't find any other similar mistakes, though.

Will fix, thanks for the report!

                        regards, tom lane


Reply | Threaded
Open this post in threaded view
|

Re: BUG #16143: PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format specifier %b is used.

Tom Lane-2
In reply to this post by Tomas Vondra-4
Tomas Vondra <[hidden email]> writes:
> The attached patch should fix this, I believe - both for %b and %B.

Yeah, I'd just come to the same conclusion.  You're welcome to
do the commits, of course.

                        regards, tom lane


Reply | Threaded
Open this post in threaded view
|

Re: BUG #16143: PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format specifier %b is used.

Tomas Vondra-4
On Fri, Nov 29, 2019 at 03:43:44PM -0500, Tom Lane wrote:
>Tomas Vondra <[hidden email]> writes:
>> The attached patch should fix this, I believe - both for %b and %B.
>
>Yeah, I'd just come to the same conclusion.  You're welcome to
>do the commits, of course.
>

OK, I'll commit shortly.

regards

--
Tomas Vondra                  http://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services


Reply | Threaded
Open this post in threaded view
|

Re: BUG #16143: PGTYPEStimestamp_fmt_asc() returns the incorrect month when the format specifier %b is used.

Tomas Vondra-4
On Fri, Nov 29, 2019 at 10:36:14PM +0100, Tomas Vondra wrote:

>On Fri, Nov 29, 2019 at 03:43:44PM -0500, Tom Lane wrote:
>>Tomas Vondra <[hidden email]> writes:
>>>The attached patch should fix this, I believe - both for %b and %B.
>>
>>Yeah, I'd just come to the same conclusion.  You're welcome to
>>do the commits, of course.
>>
>
>OK, I'll commit shortly.
>

OK, pushed with backpatch to all supported branches. Turns out this is a
pretty ancient bug - it's there since at least 2003, I stopped digging
after that.

regards

--
Tomas Vondra                  http://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services