Il bug che non ti aspetti

Per chi lavora in ambito IT è una esperienza comune sentire un utente lamentarsi per un programma che ha un errore e non funziona correttamente.
Per quanto il mondo informativo sia spesso oggetto di scherno, sappiamo che in generale gli applicativi vengono sottoposti a un debug abbastanza attento prima del rilascio e normalmente non contengono errori di grande entità, soprattutto in relazione alla loro complessità. Normalmente si tratta semplicemente di un utente che non ha mai letto il manuale e sta cercando di far fare al software qualche operazione in maniera scorreta.
Tuttavia i bug esistono e se ne trovano anche in software blasonati.

Settimana scorsa stavo scrivendo un frammento di codice che interpreta un feed RSS e crea tanti oggetti quanti sono i posts in modo da poterli manipolare all’interno della mia applicazione. Le proprietà dell’oggetto post nel mio applicativo sono fortemente tipizzate, quindi la classe post contiene una proprietà PubDate che rappresenta un oggetto di tipo DateTime. Dato che la data nel feed è semplicemente una stringa di testo, questa va sottoposta a una operazione di Parsing per essere identificata come una data.

Questo è molto semplice da fare nel .NET Framework: la data nel feed è formattata in quello che è volgarmente definito RFC1123 (che in effetti si basa sullo standard ISO8601) e il framework mette a disposizione la funzione DateTime.Parse che fa tutto il lavoro di conversione dandole semplicemente come input la stringa di testo.

Provo la funzione, tutto bene.
Tutto bene fino a quando il software non arriva a processare la data Sun, 15 Mar 2009 22:02:44 +0000.

Per qualche ragione, questa data genera un’eccezione nel parser, nonostante sia valida e correttamente formattata.
Per identificare l’errore inizio a fornire combinazioni di date e ore diverse e mi accorgo che il problema si pone solo con il mese di marzo, indipendentemente da anno, giorno o ora.
Ristretto il problema, tento una ricerca su internet e trovo un risultato pertinente su StackOverFlow.

Apparentemente ci troviamo veramente di fronte a un bug: se la Culture del codice è impostata su IT o su ES, la funzione non è in grado di interpretare il mese di marzo. Il problema non si riscontra per culture non latine, come ad esempio DE.
Faccio un’altra ricerca specifica sul bug, ma non trovo risultati, decido quindi di avviare un feedback a Microsoft su MS Connect. In pochi giorni mi viene confermato il malfunzionamento che ora è sotto analisi.

Sembra che il problema sia comune alle versioni 4.0, 4.5 e 4.5.1 di .Net, ma non ho avuto modo di provare su versioni precedenti.
Per chi volesse riprodurre il problema, riporto un frammento di codice:

Dim Row As System.Text.StringBuilder
Dim dateStrings() As String = {"Sun, 15 Mar 2009 22:02:44 +0000", "Mon, 15 Mar 2010 22:02:44 +0000", "Sun, 15 Mar 2009 2:02:44 +0000", "Mon, 15 Mar 2010 2:02:44 +0000", "Sun, 22 Mar 2009 22:02:44 +0000", "Mon, 22 Mar 2010 22:02:44 +0000", "Wed, 1 Apr 2009 22:02:44 +0000", "Thu, 1 Apr 2010 22:02:44 +0000"}

System.Threading.Thread.CurrentThread.CurrentCulture = New System.Globalization.CultureInfo("it")

For Each dateString As String In dateStrings
	Row = New System.Text.StringBuilder
	Row.Append("String is: >" & dateString & "< - ")
	Try
		Dim convertedDate As Date = DateTime.Parse(dateString)
		Row.Append("Converted " & dateString & "to " & convertedDate.Kind.ToString() & " time " & convertedDate)
	Catch ex As Exception
		Row.Append("EXCEPTION")
	End Try
	lbDateTime.Items.Add(Row.ToString)
Next

Questo codice può essere avviato semplicemente aggiungendo un controllo ListBox a un form (referenziato come lbDateTime): suggerisco a chi fosse interessato di giocare con New System.Globalization.CultureInfo(“it”) sperimentando diverse culture e verificando i risultati.

Autore: Luca Mauri

Prima di tutto un Geek e un Trekker, Luca Mauri lavora come IT Manager. Entusiasta della esplorazione spaziale e della scienza in generale. È un lettore vorace e un fotografo amatoriale. Fa parte della piccola schiera degli INTJ.

6 pensieri riguardo “Il bug che non ti aspetti”

    1. Quando mi sono buttato nel progetto in effetti pensavo che sarebbe stato un incubo.
      Al contrario, dopo qualche ricerca, devo dire che ho risolto la cosa in 30 righe di codice senza troppi problemi usando LINQtoXML.
      Al momento l’applicazione interpreta una decina di feed da fonti diverse e non ho avuto problemi oltre a quello descritto qui. Hai una criticità particolare da discutere?

      1. All’inizio mi ero scritto io un reader usando SimplePie (http://siamogeek.com/2013/03/simplepie/) poi sono passato a TTRSS (http://siamogeek.com/2013/08/tiny-tiny-rss/)
        In entrambi i casi (più nel primo che nel secondo) ho visto che ci sono un po’ di feed RSS che non rispettano XML e ci puoi fare ben poco. Alcune volte si tratta di encoding di caratteri tirati a caso, altre volte di errore nella grammatica di XML che incasina il parser.
        Per la maggior parte delle volte si tratta di blog abbastanza “underground”, ma mi dava errore di grammatica anche un blog tipo vivalafocaccia.com

        1. Se un blog che leggi gratuitamente ti fornisce un XML non valido o con caratteri non validi, purtroppo non ci puoi fare nulla.

          Quando c’è un fornitore cui paghi ogni anno somme a sei cifre che fa entrambi gli errori (e magari in un nome di un file scrive che siamo nel 20013) allora ti incavoli. Purtroppo non sono io a decidere se pagare le fatture, ma in quel caso avevo proposto di pagargli la fattura nel 20013…

Spazio per un commento