python / python/cpython

Musl libc strftime for format strings ending in %

Aperta
#127,527 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

extension-modules OS-unsupported type-bug
Lingua principale
Python
Stelle
77.2k
Fork
35.9k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

In glibc if the format string ends in %, strftime and wcsftime will turn it into a %. In musl libc, if the format string ends in %, both wcsftime and strftime return 0 with errno 0 and leave random stuff in the buffer. There's no way for us to distinguish between this and "out of space" without looking at the format string. The following 7 character patch would fix musl to behave the same as glibc:

--- a/src/time/strftime.c
+++ b/src/time/strftime.c
@@ -225,7 +225,7 @@ size_t __strftime_l(char *restrict s, size_t n, const char
*restrict f, const st
 			s[l] = 0;
 			return l;
		}
-		if (*f != '%') {
+		if (*f != '%' || !f[1]) {
 			s[l++] = *f;
 			continue;
 		}

but it sounds like musl may be against applying this patch because it is their position that the behavior is undefined? See this thread:
https://www.openwall.com/lists/musl/2022/12/19/3

So in this case, we repeatedly get format_string returning 0 and end up here:
https://github.com/python/cpython/blob/main/Modules/timemodule.c?plain=1#L844
Then if HAVE_WCSFTIME we call PyUnicode_FromWideChar(*outbuf, 0) which notices we're making an empty string and returns here:
https://github.com/python/cpython/blob/main/Objects/unicodeobject.c?plain=1#L2004-L2005
On the other hand, if !HAVE_WCSFTIME we call PyUnicode_DecodeLocaleAndSize which checks if str[len] != '\0' and raises ValueError("Embedded null byte") here:
https://github.com/python/cpython/blob/main/Objects/unicodeobject.c?plain=1#L4004

So what to do? Well for one thing, it seems to me that we can tell whether format_time is trying to return an empty string by checking if the string ends in a null byte as it should e.g., *outbuf[buflen] == 0. This can allow us to be a bit more conservative in time_strftime1.

Linked PRs
  • gh-127528

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia da Modules/timemodule.c, in particolare da time_strftime1 e dalla gestione di format_time, quindi confronta il comportamento descritto per src/time/strftime.c in musl. Riproduci un caso con un % finale tramite time.strftime ed esamina la PR collegata gh-127528. Il lavoro è completato quando il risultato dipendente dalla piattaforma viene gestito in modo coerente senza trattare un buffer non vuoto come una stringa vuota.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
c, python
Ambito
operating-systems
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
30/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.