10 novembre 2008  4

Apici, doppi apici, javascript, PHP ed HTML

Recentemente, Francesco Napoletano (meglio conosciuto come Napolux) mi ha segnalato un fastidioso, anche se poco frequente, bug presente in uno dei plug-in che ho sviluppato per Wordpress, per la precisione la Comment Toolbar.

Molto sinteticamente, nel caso in cui all’interno del nome dell’autore del commento fossero stati presenti degli apici o delle virgolette, la chiamata alle funzioni javascriptW associate alle operazione di Quote o di Reply, sarebbero fallite. Infatti a tali funzioni viene passata la stringa relativa al nome di cui sopra, direttamente come costante e, nel caso in cui i caratteri citati non siano opportunamente sostituiti con i relativi codici di escape, l’interprete javascript può erroneamente interpretare anzitempo la fine della stringa con tutte le conseguenze del caso.

Il problema è facilmente risolvibile utilizzando, lato server, la nota funzione PHPW addslashes(), che restituisce una stringa con il carattere di backslash '\' anteposto ai caratteri che richiedono il quoting nelle query dei database.

Sfortunatamente, in questo caso, questa funzione è adatta per la corretta interpretazione degli apici singoli (‘), ma non dei doppi apici (“”). Cerchiamo, quindi, di isolare il problema.

Supponiamo che il nickname del commentatore dell’articolo sia: “L’uomo nero”.

In corrispondenza del suo commento, il plugin inserirebbe dei link costruiti come segue (prendo ad esempio solo il caso del Reply)

<a href="#" onclick="CF_Reply('"L'uomo nero"'); return false;">Reply</a>

E’ evidente che, data la presenza degli apici singoli e doppi non preceduti dal backslash, non può che mandare in errore l’interprete javascript nell’analisi della stringa costante passata come parametro.

Vediamo cosa succede nel caso in cui, lato server side, si filtri e stampi la stringa con la funzione addslashes(). Il link di cui sopra cambierebbe come segue:

<a href="#" onclick="CF_Reply('\"L\'uomo nero\"'); return false;">Reply</a>

Anche in questo caso, purtroppo, verrebbe generato un errore (o meglio la funzione javascript fallirebbe durante l’esecuzione). Questa volta, però, la responsabilità è da imputare all’interprete HTMLW che, non solo non riconosce i codici escape nel formato “C like”, ma non permette neanche la nidificazione dei doppi apici, interpretandoli sempre e comunque a coppie (uno iniziale e quello immediatamente successivo come finale).

Generalmente, in questi casi, è buona norma effettuare un’operazione di “HTML Encode” ed una successiva di “HTML Decode” sulle stringhe utilizzate. Queste funzionalità, che sono ormai patrimonio di tutti i linguaggi sia server che client side, usati per lo sviluppo web, consentono di trasformare i caratteri speciali in codici interpretabili come entità singole dal linguaggio HTML.

Sfortunatamente la funzione server side PHP htmlentities() non è compatibile con quella che dovrebbe essere la “corrispondente” funzione client side javascript unescape(). Per ovviare al problema è necessario pertanto scrivere una funzione javascript ad hoc per poter effettuare l’opportuna conversione.

Nel caso specifico, a mio avviso, “il gioco non vale la candela”; aggiungere una funzione in più (peraltro anche composta da molte linee di codice) al piccolissimo script inserito in modalità in line dal mio plugin, non mi è sembrata la scelta più idonea.

Pertanto ho preferito rimuovere alla radice il problema eliminando in “maniera draconiana” i doppi apici eventualmente presenti nel nickname dell’autore del commento, semplicemente modificando la seguente linea di codice:

$Author = (string)$comment->comment_author;

come segue

$Author = addslashes(str_replace("\"", "",(string)$comment->comment_author));

alternativamente si potrebbero sostituire i doppi apici direttamente con l’entità HTML &quot; e poi successivamente effettuare nuovamente la sostituzione lato client side via javascript. Questa operazione comporterebbe una modifica veramente minimale al codice in line inserito dal plug-in (non ne escludo l’implementazione nella prossima release).

Se qualcuno desidera proporre soluzioni alternative, può come sempre servirsi dello spazio riservato ai commenti.

Esprimi il tuo giudizio

Commenti (4) -

Vinz486
Vinz486
10 nov 2008 alle 09:29  01
Ciao, anche io ho avuto spesso di questi problemi.

Per risolvere la cosa in modo "pulito" uso sempre questo ottimo riferimento kevin.vanzonneveld.net/.../

Ci sono parecchie funzioni php replicate in js. In questo caso specifico avrei usato un'encoding in base64 in modo da tagliare la testa al toro in presenza di qualsiasi carattere strano.

Ciao.
Napolux
Napolux
10 nov 2008 alle 11:22  02
E usare invece le HTML entities per stampare il JS?

&#39 (ho tolto il ; finale per farla visualizzare) per l'apice singolo
&#34 (ho tolto il ; finale per farla visualizzare) per le virgolette.

Cosi' tagli la testa al toro direttamente da PHP con la funzione htmlentities(), no? Tong
Cristiano
Cristiano
10 nov 2008 alle 13:09  03
@ Vinz486:
La libreria che tu segnali è molto interessante: solo che per usare le singole funzioni è necessario caricare l'intera libreria (ho notato infatti che ci sono dipendenze all'interno delle prime).
Come già affermato, non credo che "il gioco valga la candela" Wink

@ Napolux:
htmlentities() converte tutti i caratteri non alfanumerici, inclusa punteggiatura, separatori e quant'altro, per cui, è necessario usare una funzione di riconversione "gemella" da javascript per poi "scrivere" il testo decodificato nella textarea del commento. (non avrebbe senso riconvertire solo apici singoli e doppi)
Sfortunatamente non esiste un'equivalente funzione built-in ...
(... mi sembrava di averlo già scritto però Smile )
Napolux
Napolux
10 nov 2008 alle 16:43  04
@ Cristiano:
Ops, l'avevo letto, ma me l'ero persa Tong

Aggiungi Commento

biucitecode
  • Commento
  • Anteprima
Loading


| |   |  

Codice QR

Codice QR - cristianofino.net

Ultimi Commenti