Come gestire le virgolette negli attributi degli shortcode in WordPress

8 mar 2013, 17:18:01
Visualizzazioni: 15.6K
Voti: 5

Sto cercando di capire come gestire le virgolette (singole e doppie) negli attributi degli shortcode.

Il problema è che il contenuto viene inserito dall'utente e quindi potrebbe potenzialmente includere virgolette " e '. Con le virgolette doppie, l'attributo dello shortcode smette di funzionare correttamente, ad esempio:

attributo="testo qui con "virgolette" che interrompe l'attributo..."

Invece di ottenere l'intera stringa, si ferma alla seconda coppia di virgolette.

So che si potrebbe usare le virgolette singole, ma questo creerebbe lo stesso problema se l'utente usasse virgolette singole nel testo.

Ho esaminato varie soluzioni PHP/WP ma nessuna sembra funzionare, come esc_html, htmlspecialchars, htmlentities.

Forse ho configurato male o non sto applicando la codifica nel punto giusto.

Attualmente sto usando questo codice per lo shortcode (semplificato):

function aps_person_schema_shortcode( $atts, $content = null)   {

extract( shortcode_atts( array(     
            'aps_person_description' => ''
        ), $atts
    )
);

$aps_person_return = '<div class="aps_person_container aps_container">';
$aps_person_return .= '<p class="aps_person_description" itemprop="description">' . $aps_person_description . '</p>';
$aps_person_return .= '</div>';

return $aps_person_return;

}
add_shortcode('aps_person', 'aps_person_schema_shortcode');

Ho provato ad aggiungere dopo l'array extract cose come:

$aps_person_description = esc_html($atts['aps_person_description']); 

ma poiché l'attributo è già rotto (print_r mostra che la stringa dopo la virgoletta è separata in un elemento array per ogni parola), l'escape della stringa non funziona.

Provato anche prima dell'array ma non funziona e ottengo un Notice: Undefined index

Quindi, per chiarire, come si può sanificare l'input utente per i dati degli attributi degli shortcode?

0
Tutte le risposte alla domanda 3
1

Si scopre che il sistema degli shortcode di WordPress utilizza la funzione shortcode_parse_atts($text); per analizzare una voce di shortcode e recuperare i nomi e i valori degli attributi, memorizzandoli in coppie nell'array $atts, che viene poi passato alla funzione dello shortcode. Quindi, nel tuo caso, aggiungere azioni di escape nella funzione dello shortcode come questa:

$aps_person_description = esc_html($atts['aps_person_description']); 

non funzionerà perché shortcode_parse_atts() ha già recuperato i nomi e i valori degli attributi e potrebbe aver interpretato erroneamente le virgolette nei valori degli attributi.

Per approfondire, la funzione shortcode_parse_atts() utilizza questo pattern regex:

/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/

per riconoscere i nomi e i valori degli attributi nei seguenti formati:

1. attr1="value1"
2. attr2='value2'
3. attr3=value3
4. "value4"
5. value5

Quindi, se un utente inserisce virgolette nei valori, può facilmente andare storto. Ad esempio:

[my_shortcode dog='Santa's Little Helper' /]    
// $attr è Array ( [0] => dog='Santa's [1] => Little [2] => Helper' )
// dovrebbe essere Array ( [dog] => Santa's Little Helper )

Sanificare dopo l'analisi è ovviamente troppo tardi, che ne dici di sanificare prima dell'analisi? Dovremmo sanificare l'intera voce poiché non abbiamo ancora alcun valore di attributo su cui lavorare. Ma anche questo causa problemi, ad esempio:

html_entities("[my_shortcode dog='Santa's Little Helper' /]", ENT_QUOTES);
// ora la voce è [my_shortcode dog=&#039;Santa&#039;s Little Helper&#039; /]
// dopo l'analisi: 
Array
(
    [dog] => &#039;Santa&#039;s
    [0] => Little
    [1] => Helper&#039;
)

Il paradosso è: per assicurarsi che il motore di analisi analizzi correttamente, devi sanificare i valori degli attributi; ma per farlo devi prima eseguire il motore di analisi per ottenere i valori.

In conclusione, penso che il modo ragionevole per assicurarsi che tutto vada bene sia garantire che gli utenti inseriscano gli attributi in formati corretti. Una volta che gli utenti inseriscono attributi mal formattati, sarà un grosso problema. Per tua informazione, la mia esperienza è di utilizzare $content. Nel tuo caso, metterei aps_person_description nel $content, potrebbe apparire così:

[my_shortcode]testo qui con "virgolette" che interrompono l'attributo...[/my_shortcode]

e le virgolette saranno meno un problema.

28 lug 2013 06:09:01
Commenti

Non c'è alcun paradosso, è un semplice ma significativo difetto in shortcode_parse_atts(). Semplicemente non è così che si dovrebbero analizzare gli attributi tra virgolette. Le sequenze di escape sono fondamentali, non troverai un linguaggio di programmazione senza di esse. Avrebbe dovuto includere questa funzionalità fin dall'inizio. Il tuo esempio potrebbe essere facilmente scritto come [my_shortcode dog='Santa\'s Little Helper' /] se il parser avesse un minimo di intelligenza.

Walf Walf
27 feb 2015 04:51:03
1

Sembra che tu stia lavorando sull'estremità sbagliata.

Prova a sanitizzare l'input dell'utente, ad esempio utilizzando sanitize_text_field, non l'output dello shortcode.

8 mar 2013 17:25:30
Commenti

Grazie! Anche se non ho usato il sanitize_textfield mi hai riportato sulla strada giusta. L'input viene aggiunto con jQuery quindi ho aggiunto un .replace per cambiare le virgolette, non è perfetto ma evita che si rompa.

Apina Apina
8 mar 2013 20:41:32
0

Mi sono trovato di fronte a un problema simile quando dovevo stampare una variabile PHP all'interno di un attributo di uno shortcode. Nel mio caso, il valore era il nome di un termine di tassonomia, non un contenuto generato dall'utente, quindi non c'era input da sanitizzare.

Utilizzando htmlentities() con il flag ENT_QUOTES è possibile utilizzare stringhe che includono ' e " come attributi di shortcode. Tuttavia, questa funzione converte anche altri caratteri in entità HTML, ad esempio & in &amp;, il che non era ideale per il mio caso.

Per convertire solo i caratteri ' e " in entità HTML, senza modificare altri caratteri come &:

htmlspecialchars_decode( htmlentities($value_to_print, ENT_QUOTES), ENT_NOQUOTES )

htmlspecialchars_decode() inverte tutte le entità HTML convertite da htmlentities(). Utilizzando il flag ENT_NOQUOTES si impedisce che i caratteri ' e " vengano riconvertiti.

19 mar 2022 03:51:45