Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Dec 2009 04:55:08 GMT
From:      Denis Chatelain <denis@tikuts.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/141939: strptime confuses July with June with the fr_FR locale
Message-ID:  <200912240455.nBO4t8TY083080@www.freebsd.org>
Resent-Message-ID: <200912240500.nBO50CSl001050@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         141939
>Category:       kern
>Synopsis:       strptime confuses July with June with the fr_FR locale
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 24 05:00:12 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Denis Chatelain
>Release:        7.2
>Organization:
>Environment:
FreeBSD (snip) 7.2-RELEASE-p4 FreeBSD 7.2-RELEASE-p4 #0: Fri Oct  2 08:22:32 UTC 2009     root@amd64-builder.daemonology.net:/usr/obj/usr/src/sys/GENERIC  amd64

>Description:
strptime has a bug with the fr_FR locale: when using the %B switch it will return June (juin) instead of July (juillet) when parsing it.

Here's how it goes when parsing "juillet":
(check all months until may, then June, "juin")
- check for full month "juin" -> no match
- check for abbreviated June month "jui" -> match; wrong, and it breaks without checking for juillet, effectively returning June.

it returns NULL iff there pattern has something else after it (month year), silently misreading the month

It does not seems to be fixed in later version (ie: 8.O)
>How-To-Repeat:
Feed "juillet" to this program, and you get the output "juin" instead of "juillet" (with no indication of failure):

#include <time.h>
#include <locale.h>
#include <string.h>
#include <stdio.h>

int main (int argc, char *argv[])
{
char TheoricallyIdenticalDate[255];
char OriginalDate [255] ;
char *result;
struct tm timeptr;

if (argc != 2)
        return 1;

strlcpy (OriginalDate, argv[1], sizeof (OriginalDate));

setlocale (LC_TIME, "fr_FR.UTF-8");

memset (&timeptr, 0, sizeof (struct tm));
result = strptime (OriginalDate, "%B", &timeptr);
if (result == 0)
        printf ("Failed parsing the date\n");

strftime (TheoricallyIdenticalDate, 255, "%B", &timeptr);

printf ("before parsing: %s, after parsing: %s\n", OriginalDate, TheoricallyIdenticalDate);

return 0;
}

>Fix:
Check all full months first, then check abbreviations.

That's my proposed patch.

However, in the unpredictable world of languages, some could have month abbreviations longer than the full month names, so a more correct approach could to be to try to match the longest strings first, independently of the nature of the string (full or abbreviated).

Patch attached with submission follows:

--- /usr/src/lib/libc/stdtime/strptime.c	2009-04-15 05:14:26.000000000 +0200
+++ strptime.c	2009-12-24 05:34:10.000000000 +0100
@@ -408,6 +408,11 @@
 					if (strncasecmp(buf, tptr->month[i],
 							len) == 0)
 						break;
+                                }
+                        }
+                        // Try the abbreviated month name if the full name wasn't found and Oalternative was not requested
+			if (i == asizeof(tptr->month) && !Oalternative) {
+				for (i = 0; i < asizeof(tptr->month); i++) {
 					len = strlen(tptr->mon[i]);
 					if (strncasecmp(buf, tptr->mon[i],
 							len) == 0)


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200912240455.nBO4t8TY083080>