git: 581d5098ec2c - main - libfetch: Use C locale for dates

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Mon, 02 Nov 2026 12:38:01 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=581d5098ec2c9738db8a98bb1ef3c36ca33033b9

commit 581d5098ec2c9738db8a98bb1ef3c36ca33033b9
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-11-02 12:27:46 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-11-02 12:28:39 +0000

    libfetch: Use C locale for dates
    
    MFC after:      1 week
    PR:             299084
    Reviewed by:    arrowd, kevans
    Differential Revision:  https://reviews.freebsd.org/D60901
---
 lib/libfetch/http.c | 28 +++++++++++++++++++---------
 1 file changed, 19 insertions(+), 9 deletions(-)

diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c
index 8fe98c57446d..feb88f9c1452 100644
--- a/lib/libfetch/http.c
+++ b/lib/libfetch/http.c
@@ -77,6 +77,7 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#include <xlocale.h>
 
 #ifdef WITH_SSL
 #include <openssl/md5.h>
@@ -121,6 +122,15 @@
 
 #define HTTP_ERROR(xyz) ((xyz) >= 400 && (xyz) <= 599)
 
+static locale_t
+fetch_time_locale(void)
+{
+	static locale_t loc;
+
+	if (loc == NULL)
+		loc = newlocale(LC_TIME_MASK, "C", NULL);
+	return (loc);
+}
 
 /*****************************************************************************
  * I/O functions for decoding chunked streams
@@ -854,20 +864,20 @@ out:
 static int
 http_parse_mtime(const char *p, time_t *mtime)
 {
-	char locale[64], *r;
 	struct tm tm;
+	char *r;
 
-	strlcpy(locale, setlocale(LC_TIME, NULL), sizeof(locale));
-	setlocale(LC_TIME, "C");
-	r = strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm);
+	r = strptime_l(p, "%a, %d %b %Y %H:%M:%S GMT", &tm,
+	    fetch_time_locale());
 	/*
 	 * Some proxies use UTC in response, but it should still be
 	 * parsed. RFC2616 states GMT and UTC are exactly equal for HTTP.
 	 */
-	if (r == NULL)
-		r = strptime(p, "%a, %d %b %Y %H:%M:%S UTC", &tm);
+	if (r == NULL) {
+		r = strptime_l(p, "%a, %d %b %Y %H:%M:%S UTC", &tm,
+		    fetch_time_locale());
+	}
 	/* XXX should add support for date-2 and date-3 */
-	setlocale(LC_TIME, locale);
 	if (r == NULL)
 		return (-1);
 	DEBUGF("last modified: [%04d-%02d-%02d %02d:%02d:%02d]\n",
@@ -1647,8 +1657,8 @@ http_request_body(struct url *URL, const char *op, struct url_stat *us,
 
 		if (ims && url->ims_time) {
 			timestruct = gmtime((time_t *)&url->ims_time);
-			(void)strftime(timebuf, 80, "%a, %d %b %Y %T GMT",
-			    timestruct);
+			(void)strftime_l(timebuf, 80, "%a, %d %b %Y %T GMT",
+			    timestruct, fetch_time_locale());
 			if (verbose)
 				fetch_info("If-Modified-Since: %s", timebuf);
 			http_cmd(conn, "If-Modified-Since: %s", timebuf);