Details

[Home]

Issue of the Implementation # S0520_1

Brief

Incorrect processing of some conversion specifications by getdate() and strptime() functions

Detailed Description

There are some problems in getdate() function.

  1. Conversion specifications "%S" and "%M" are not processed, when used without "%H" conversion specification.
  2. Templates "%Y", "%y", "%d", "%C", "%C %y", "%C %y %m" are not processed separately.
  3. When template is "%Y %m", day of month is not set to 1 as the POSIX standard requires.

Also there is a problem in strptime() function.

  1. While using "%U", "%W" no data is written in corresponding fields of structure tm.

The sample code below reproduces these problems. Call the compiled program with the parameter, that specify a path to file, where templates will be stored.

Problem location(s) in the standard

Linux Standard Base Core Specification 3.1, Chapter 13. Base Libraries, 13.5. Interface Definitions for libc, description of getdate() function.

Example

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

struct tm *getdate(const char *string);
char* templ_filename;
extern int getdate_err;

// Writes template given as parameter to file,
// specified as the argument
void outputToTemplateFile(char* str)
{
    FILE *fd=fopen(templ_filename, "w");
    if(fd==NULL)
    {
        printf("Can not open file for writing\n");
        exit(1);
    }

    fprintf(fd, "%s\n", str);
    fclose(fd);
}

// Calls getdate() function with specified parameter,
// specified as the argument, also checks the contents of
// file with template and prints the result
void processGetdateOn(char* str)
{
struct tm * res;
char templ[1000];
FILE *fd=fopen(templ_filename, "r");

    if(fd==NULL)
    {
        printf("Can not open file for reading\n");
        exit(1);
    }

    if(fgets(templ, 1000, fd)==NULL)
    {
        printf("Can not read file\n");
        exit(1);
    }
    fclose(fd);

    res=getdate(str); 
    if(res==NULL)
    {
        printf("Failed on getdate(\"%s\"), template is: %s", str, templ);
        printf("Error number: %d\n\n", getdate_err);
    }
    else
    {
        printf("Success on getdate(\"%s\"), template is: %s\n",  str, templ);
        printf("Result is\n");
        printf("Seconds: %d\n", res->tm_sec);
        printf("Minutes: %d\n", res->tm_min);
        printf("Hour: %d\n", res->tm_hour);
        printf("Day of month: %d\n", res->tm_mday);
        printf("Month of year: %d\n", res->tm_mon);
        printf("Years since 1900: %d\n", res->tm_year);
        printf("Day of week: %d\n", res->tm_wday);
        printf("Day of year: %d\n", res->tm_yday);
        printf("Daylight Savings flag: %d\n\n", res->tm_isdst);
    }
}

// Executes strptime() function with parameters
// buf and format and prints the result
void processStrptimeOn(char* buf, char* format)
{
char *res;
struct tm tms;
	
    res=(char*)strptime(buf, format, &tms); 
    if(res!=NULL)
    {
        printf("Result of strptime() on template %s and buf %s is\n", format, buf);
        printf("Seconds: %d\n", tms.tm_sec);
        printf("Minutes: %d\n", tms.tm_min);
        printf("Hour: %d\n", tms.tm_hour);
        printf("Day of month: %d\n", tms.tm_mday);
        printf("Month of year: %d\n", tms.tm_mon);
        printf("Years since 1900: %d\n", tms.tm_year);
        printf("Day of week: %d\n", tms.tm_wday);
        printf("Day of year: %d\n", tms.tm_yday);
        printf("Daylight Savings flag: %d\n\n", tms.tm_isdst);
    }
    else
    {
        printf("Error: strptime()\n");
    }
}

int
main (int argc, char* argv [])
{

    if(argc < 2)
    {
        printf("Command line: progname template_filename_full_path\n");
        exit(1);
    }
    templ_filename=argv[1];

    setenv("DATEMSK", templ_filename, 1);

    /*
     * The following 4 testcases reproduce the problem:
     * 1. Templates "%S" and "%M" are not processed, 
     *    when used without "%H" template
     */	
    outputToTemplateFile("%M"); 
    processGetdateOn("1");     // Bug: getdate() returns error
 
    outputToTemplateFile("%M %H");
    processGetdateOn("1 2");   // OK

    outputToTemplateFile("%S");
    processGetdateOn("1");     //Bug: getdate() returns error

    outputToTemplateFile("%S %H");
    processGetdateOn("1 2");   // OK

    /*
     * The following 9 testcases reproduce the problem:
     * 2. Templates "%Y", "%y", "%d", "%C", "%C %y" 
     *    are not processed separately
     */	
    outputToTemplateFile("%Y");
    processGetdateOn("2001");     // Bug: getdate() returns error

    outputToTemplateFile("%Y %m");
    processGetdateOn("2001 3");   // OK
		
    outputToTemplateFile("%y");
    processGetdateOn("70");       // Bug: getdate() returns error

    outputToTemplateFile("%y %m");
    processGetdateOn("70 3");     // OK
		
    outputToTemplateFile("%d");
    processGetdateOn("06");       // Bug: getdate() returns error

    outputToTemplateFile("%d %m");
    processGetdateOn("25 3");     // OK

    outputToTemplateFile("%C");
    processGetdateOn("98");       // Bug: getdate() returns error

    outputToTemplateFile("%C %y %m");
    processGetdateOn("98 3 2");   // Bug: getdate() returns error
		
    outputToTemplateFile("%C %y");
    processGetdateOn("21 5");     // Bug: getdate() returns error

    /*
     * The following testcase reproduces the problem:
     * 3. When template is "%Y %m", day of month is not set 
     *    to 1 as standard requires 
     */	
    outputToTemplateFile("%Y %m");
    processGetdateOn("2008 3");   // Bug in getdate(): 
                                  // day of month is not 1 as required by POSIX

    /*
     * The following testcases reproduce the problem
     * of strptime().
     * 1. While using "%U", "%W" nothing happens.
     */	
    processStrptimeOn("3", "%U");
    processStrptimeOn("3", "%W");
	
    return 0;
}

Component

glibc 2.3.4 or later

Accepted

Red Hat Bugzilla, 5451

Status

Fixed in glibc-2.8

[Home]