Evadarea ghilimelelor din atributele shortcode-urilor în WordPress

8 mar. 2013, 17:18:01
Vizualizări: 15.6K
Voturi: 5

Am încercat să aflu cum să evit problemele cu ghilimelele (simple și duble) din atributele shortcode-urilor.

Practic, conținutul este scris de utilizator și prin urmare poate include ghilimele " și '. Problema este că ghilimelele " întrerup funcționarea atributului shortcode-ului, de exemplu:

attribut="text care conține "ghilimele" și întrerupe atributul...."

Deci, în loc să obținem întregul șir, acesta se oprește la a doua pereche de ghilimele.

Știu că s-ar putea configura cu ghilimele simple, dar asta creează aceeași problemă dacă un utilizator folosește ghilimele simple în text.

Am căutat diverse soluții PHP/WP dar nu reușesc să le fac să funcționeze, cum ar fi esc_html, htmlspecialchars, htmlentities.

Poate le-am configurat greșit sau nu aplic codificarea în locul potrivit.

Momentan folosesc acest cod (fără codificare) pentru shortcode (simplificat):

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');

Am încercat să adaug după array-ul extract lucruri precum:

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

dar cum atributul este deja stricat (print_r arată că șirul după ghilimele este separat în elemente de array pentru fiecare cuvânt), escaparea șirului acolo nu funcționează.

Am încercat înainte de array și nu funcționează - primesc o Notificare: Index nedefinit

Deci, pentru a clarifica, cum poți să sancționezi datele introduse de utilizator pentru atributele shortcode-urilor?

0
Toate răspunsurile la întrebare 3
1

Se pare că sistemul de shortcode-uri din WordPress utilizează funcția shortcode_parse_atts($text); pentru a analiza o intrare de shortcode și a extrage numele și valorile atributelor, stocându-le în perechi în array-ul $atts, care este apoi transmis funcției shortcode-ului. Deci, în cazul tău, adăugarea acțiunilor de escaping în funcția shortcode ca aceasta:

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

nu va funcționa deoarece shortcode_parse_atts() a extras deja numele și valorile atributelor și ar fi putut interpreta greșit ghilimelele din valorile atributelor.

Pentru a analiza mai în detaliu, funcția shortcode_parse_atts() utilizează acest model regex:

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

pentru a recunoaște numele și valorile atributelor în următoarele formate:

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

Deci, dacă un utilizator introduce ghilimele în valori, poate apărea cu ușurință o eroare. De exemplu:

[my_shortcode dog='Santa's Little Helper' /]    
// $attr este Array ( [0] => dog='Santa's [1] => Little [2] => Helper' )
// ar trebui să fie Array ( [dog] => Santa's Little Helper )

Sanitizarea după parsare este evident prea târziu, dar ce zici de sanitizarea înainte de parsare? Va trebui să sanitizăm întreaga intrare, deoarece nu avem încă valori ale atributelor cu care să lucrăm. Dar și asta cauzează probleme, de exemplu:

html_entities("[my_shortcode dog='Santa's Little Helper' /]", ENT_QUOTES);
// acum intrarea este [my_shortcode dog=&#039;Santa&#039;s Little Helper&#039; /]
// după parsare: 
Array
(
    [dog] => &#039;Santa&#039;s
    [0] => Little
    [1] => Helper&#039;
)

Paradoxul este: pentru a te asigura că motorul de parsare analizează corect, trebuie să sanitizezi valorile atributelor; dar pentru a face asta, trebuie mai întâi să rulezi motorul de parsare pentru a obține valorile.

În concluzie, cred că soluția rezonabilă pentru a te asigura că totul merge bine este să te asiguri că utilizatorii introduc atributele în formate corecte. Odată ce utilizatorii postează atribute prost formatate, va fi o mare bătaie de cap. Ca informație, experiența mea este să utilizez $content. În cazul tău, aș pune aps_person_description în $content, ar putea arăta astfel:

[my_shortcode]text aici cu "ghilimele" care ar putea întrerupe atributul...[/my_shortcode]

și ghilimelele vor fi mai puțin problemă.

28 iul. 2013 06:09:01
Comentarii

Nu există niciun paradox, este o simplă dar semnificativă greșeală în shortcode_parse_atts(). Pur și simplu nu așa ar trebui să analizezi atributele între ghilimele. Secvențele de escapare sunt esentiale, nu vei găsi un limbaj de programare fără ele. Ar fi trebuit să aibă această funcționalitate încorporată încă de la început. Exemplul tău ar fi putut fi scris cu ușurință ca [my_shortcode dog='Santa\'s Little Helper' /] dacă parserul ar fi avut vreo idee.

Walf Walf
27 feb. 2015 04:51:03
1

Se pare că lucrezi la capătul greșit.

Încearcă să saniezi datele introduse de utilizator, de exemplu prin intermediul sanitize_text_field, nu rezultatul shortcode-ului.

8 mar. 2013 17:25:30
Comentarii

Mulțumesc! Deși nu am folosit funcția sanitize_textfield, m-ai condus înapoi acolo unde trebuia să fiu. Input-ul este adăugat cu jQuery, așa că am adăugat un .replace pentru a schimba ghilimelele, nu e perfect dar împiedică funcționarea defectuoasă.

Apina Apina
8 mar. 2013 20:41:32
0

Am întâmpinat o problemă similară atunci când am încercat să afișez o variabilă PHP într-un atribut de shortcode. În cazul meu, valoarea era un nume de termen de taxonomie, nu conținut generat de utilizator, așa că nu a fost nevoie de nicio operație de curățare a datelor.

Folosirea funcției htmlentities() cu flag-ul ENT_QUOTES permite utilizarea șirurilor care conțin caracterele ' și " ca atribute de shortcode. Totuși, această funcție convertește și alte caractere în entități HTML, cum ar fi transformarea lui & în &amp;, ceea ce nu era ideal în situația mea.

Pentru a converti doar caracterele ' și " în entități HTML, fără a afecta alte caractere precum &:

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

htmlspecialchars_decode() anulează toate conversiile în entități HTML efectuate de htmlentities(). Folosind flag-ul ENT_NOQUOTES, prevenim reconversia caracterelor ' și " înapoi în forma lor originală.

19 mar. 2022 03:51:45