Visualizzazione dei risultati da 1 a 9 su 9
  1. #1
    Utente di HTML.it L'avatar di flessciato
    Registrato dal
    Jun 2002
    Messaggi
    1,522

    PILLOLA - PATTERN e VALIDAZIONE STRINGHE

    RICERCA DI PATTERN E VALIDAZIONE DELLE STRINGHE (ANCHE ESPRESSIONI REGOLARI).

    PRIMA PARTE:

    Su questo argomento ho trovato molte cose sparse per la rete. Tuttavia trattavano in modo sommario l'argomento del titolo. In questo pillolotto descriverò (o meglio tenterò di...) spiegare nel modo più semplice possibile come gestire le stringhe per renderle valide a dei parametri da noi settati (ovvero renderle conformi ad un pattern). Le tecniche prese in esame sono utili per validare l'input dei form e per controllare i campi che vengono passati ad una query, prevenendo in modo abbastanza certo l'SQL injectiono l'inserimento di codice “malevolo” nel form o nella query-string del browser. L'argomento “sicurezza” preso in oggetto quindi è circostanziato al passaggio che avviene tra form e query a livello di PHP. Eventuali controlli sulle sessioni e sul database (che avvengono rispettivamente prima e dopo questo passaggio) non sono trattate. Dovete cercare quindi qualche altra pillola per l'argomento affinchè sia chiaro come gestire in modo sicuro tutto il processo.

    Un argomento correlato a questo lo potete trovare qui http://forum.html.it/forum/showthrea...hreadid=392715

    Ok, partiamo subito con un esempio:

    codice:
    <?php
    $frase="ciao mondo, come va oggi pomeriggio?";
    $mio_array=explode(" ", $frase);
    foreach($mio_array as $parola_da_cercare){
    	if($parola_da_cercare == "oggi") echo "oggi è stato trovato";
    }
    ?>
    Questo script fa una cosa semplicissima: prende una frase e la salva in una variabile ($frase). Poi creo una variabile $mio_array (che dovrà contenere i “pezzi” della frase che sto cercando).
    A $mio_array assegno la funzione explode(9 che prende due parametri: il primo è detto delimitatore mentr il secondo è la frase che voglio far “esplodere” nelle sue parti. Explode(), in sostanza scompone la mia frase in tante parole che sono delimitate da uno spazio (il mio delimitatore).

    Poi facendo un ciclo ricerco nell'array la parola specificata (in questo caso l'ho scritta direttamente ma poteva benissimo provenire da un form...che poi validerò). Se la parola esiste mi stampa una frase.

    Per controllare effettivamente la funzione explode (cioè, come opera) provate a scrivere questo esempio

    codice:
    <?php
    $frase="ciao mondo, come va oggi pomeriggio?";
    $mio_array=explode(" ", $frase);
    foreach($mio_array as $parola_da_cercare){
    	if($parola_da_cercare == "oggi") echo "'oggi' è stato trovato
    ";
    	else echo "- non ho trovato la parola cercata
    ";
    }
    ?>
    Questo esempio mostra come il ciclo confronti effettivamente le parole dell'array (esploso) e la parola della mia ricerca (contenuta nell'istruzione if).

    Questo è il risultato:

    - non ho trovato la parola cercata
    - non ho trovato la parola cercata
    - non ho trovato la parola cercata
    - non ho trovato la parola cercata
    'oggi' è stato trovato
    - non ho trovato la parola cercata
    fate caso che la riga trovata è la quinta (anche nella frase la parola “oggi” è al quinto posto, se calcoliamo che ogni parola occupa un posto).

    Il problema però nasce quando vogliamo trovare una parola specifica. Ma come? E fino adesso che abbiamo fatto?! :-) Le parole esplose si portano dietro tutta la punteggiatura. Se trasformate infatti “pomeriggio?” in “pomeriggio ?” noterete che le righe ora sono 7. Php quindi tratta ogni singola porzione di caratteri delimitati dagli spazi come una parola (e quindi anche un sinologp unto di domanda o una virgola). Il nostro esempio non funziona ricercando la parola “mondo”, perchè contiene la virgola.

    La funzione ereg() invece cerca ESATTAMENTE la frase che passate come parametro.

    Questo esempio fa la stessa cosa dell'array esploso con il ciclo senza badare alla punteggiatura:

    codice:
    <?php 
    $frase="ciao mondo, come va oggi pomeriggio?";
    	if(ereg("mondo", $frase)) echo "'mondo' è stato trovato
    ";
    ?>
    usando gli array aggiungo un parametro ad ereg()

    codice:
    <?php
    $frase="ciao mondo, come va oggi pomeriggio?";
    	if(ereg("mondo", $frase, $mio_array)) echo "$mio_array[0] è stato trovato
    ";
    ?>
    il terzo parametro di ereg() salva il risultato in un array con nome arbitrario. La stringa cercata quindi avrà indice 0 (come già sapete, l'array parte da 0 e non da 1).

    Ora arriva il bello. Cosa c'entrano questi esempi con la sicurezza? Immaginate questo: un utente compila un form con i suoi dati, o un login per autenticarsi in un'area riservata. Potrebbe passare qualsiasi parametro

    Ad esempio un mancato controllo ad un form potrebbe passare un istruzione SQL creando un'autenticazione fittizzia. Molti conosceranno un esempio del tipo 'A' OR 'B'='B'.

    Questa istruzione SQL fa una cosa molto semplice: logga chi compila il form perchè alla funzione viene passata un'istruzione legittima (infatti il modulo non controlla che ci siano parametri cazzuti passati).

    Quindi il controllo non lo fa più la funzione ma l'istruzione passata. Questo bisogna prevenirlo. Consiglio una lettura della pillola sull'SQL injection a completezza di questa.

    I caratteri “riservati” a PHP che non possono essere cercati sono:

    () [] {} | \ $ . * ? + ^

    Se volete usare questi parametri in una ricerca per delimitare la stringa dovete semplicemente anteporre una barra rovesciata. Il carattere speciale diventerà una semplice stringa. Quindi per delimitare la parola/lettera $ fate ereg(“$”, “oggi ho preso molti \$”) e così via...

    Ad esempio:

    codice:
    <?php
    $frase="oggi sono senza soldi per la cena";
    $corrispondenza="soldi....";
    	if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' è stato trovato
    ";
    ?>
    Darà come risultato: 'soldi pe' è stato trovato .
    Mentre scrivendo così $corrispondenza="soldi\.\.\.\.", non da un bel niente. Se la frase contiene la stringa soldi.... allora viene trovata.

    Chiarito questo semplice aspetto delle stringhe (i caratteri speciali) torniamo andiamo avanti con il controllo sulle stringhe.

    Vogliamo prevenire l'inserimento di qualsiasi carattere che non ci piace ed in più vogliamo essere sicuri che non vengano inserite cazzate nei form.

    Per far validare una stringa stringa si possono negare od accettare dei caratteri. I caratteri messi tra parentesi quadra sono accettati mentre quelli preceduti dal simbolo ^ non lo sono.

    Ad esempio

    Sto cercando dentro una frase
    codice:
    <?php
    $frase="oggi sono contento";
    $corrispondenza="content[oa]";
    	if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' è stato trovato
    ";
    ?>


    se nella frase metto contenta vengono accettate le ricerche. Se il mio esempio ha invece

    codice:
    $corrispondenza="content[^oa]";
    La frase non viene trovata perchè sto dicendo a php di trovare tutte quelle parole che uguali a content che NON finiscano con a oppure o. Se mettessi “contenti funzionerebbe.

    Questo piccolo esempio è embrionale per capire che cosa si vuole accettare in una stringa.

    Un metodo semplice per far accettare le stringhe è quello di utilizzare le scorciatoie. Poi le vediamo
    Slack 10 - Apple G5 2.5 - winzoz xp
    php/mysql/apache
    Flash MX / roba in 3D / roba per il video e l'audio

  2. #2
    Utente di HTML.it L'avatar di flessciato
    Registrato dal
    Jun 2002
    Messaggi
    1,522

    SECONDA PARTE

    SECONDA PARTE

    Le scorciatoie permettono di prendere un range di caratteri, numeri o stringe senza specificarli uno per volta.

    Ad esempio ^1234567890 equivale a [^0-9].

    Ci sono delle scorciatoie monolettera ora le vediamo

    1)\d è uguale a [0-9]
    2)\w è uguale a [0-9A-Za-z_]
    3)\s è uguale a [ \t\n\r] ovvero alla spaziatura tra le stringhe

    Per creare delle negazioni si fa semplicemente [^0-9] e così via. Quindi la stringa accetta tutto tranne che numeri.

    Per verificare se una frase (o un termine) comincia o termina con un particolare carattere (anche speciale, basta mettere la \) si usano rispettivamente ^ e $. Tipo “questo è il mio pc” come stringa, e come corrispondenza .

    Per verificare una parola od un altra si usa il delimitatore “ | “. Quindi “casa | chiesa” ricerchera UNO DEI DUE termini.

    I QUALIFICATORI (sono 3)

    Per rendere facoltativa una selezione si usa il carattere “ ? “. Ad esempio “panno” diventarà “p?anno” la ricerca cercherà o panno o anno.

    Un utilizzo misto di queste tecniche permette di ottenere risultati molto precisi, poi le vedremo... Ad esempio le parentesi tonde permettono che ciò che sia messo tra parentesi sia selezionato ma in modo opzionale come nell'esempio precedente (ma che riguardava solamente un carattere). Ad esempio “(ca)?panna” diventerà “o panna o capanna”. Il punto di domanda ricorda vagamente l'operatore ternario ( a>b ? a>b : a<b ) . Se le prima è vera prendi il secondo valore, se è falsa prendi il terzo.

    Il secondo qualificatore è il “+”. In sostanza prende solo la parte (se esiste) di carattere dopo il + indipendentemente dalla lunghezza della stringa
    codice:
    <?php
    $frase="non mi piacciono i salatini piccanti";
    $corrispondenza="salat+i";
    	if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' e' stato trovato
    ";
    ?>
    Da come risultato “non mi piacciono i salati” (o meglio, salati è stato trovato :-P).

    L'ultimo qualificatore per cercare dentro una stringa è l'asterisco *. E' come il segno + con la differenza che il valore (il carattere) successivo alla + può anche non esistere.

    codice:
    <?php
    $frase="non mi piacciono i salatini piccanti";
    $corrispondenza="salat+i";
    	if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' e' stato trovato
    ";
    ?>
    Esempio di utilizzo misto:
    codice:
    <?php
    $frase="non mi piacciono i salatini";
    $corrispondenza="pia*[a-z]";
    	if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' e' stato trovato
    ";
    ?>
    e se volessi cercare la parola intera partendo però solo da un pezzo? Questo esempio può tornare utile
    codice:
    <?php
    $frase="non mi piacciono i salatini";
    $corrispondenza="pia*[a-z]*[a-z]";
    	if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' e' stato trovato
    ";
    ?>
    Detto questo quantifichiamo una stringa.

    In tal senso si può specificare di quanto in una stringa può avanzare la nostra ricerca . Con “di quanto” intendo dire che impostando un parametro si può chiedere alla funzione ereg() di scorrere in avanti nella riga solamente del numero di caratteri settati (e anche del tipo do caratteri settati

    Esempio:
    codice:
    <?php
    $frase="non mi piacciono i salatini piccanti piccantini piccantissimi";
    $corrispondenza="picca[a-z]{1,3}";
    	if(ereg($corrispondenza, $frase, $mio_array)) echo "'$mio_array[0]' e' stato trovato
    ";
    ?>
    in questo esempio trovate la corrispondenza con piccanti. Adesso sostituite 1,3 con 1,2 e poi con 1,1 . Noterete che la ricerca avanza del numero di caratteri che settate nel secondo parametro tra le graffe. Il primo parametro fa riferimento alla parte di stringa iniziale il secondo a quella finale. Il primo indica quindi di ricercare da un carattere in poi fino a 3. Il secondo di ricercare fino al terzo carattere (di quella stringa). Se settate infatti 50 trovate sempre e solo la stringa richiesta.

    Si possono anche settare i parametri in questa maniera {1,} o {,3}. La ricerca avanzerà o DAL punto 1 fino alla fine della parola o (nel secondo caso) fino ad un massimo di 3 caratteri partendo da 1 (che quando non viene settato è sottointeso).

    La terza parte della pillola mi permette di validare la registrazione di un utente.

    Poniamo il caso che il login (per la registrazione) di un utente si basi sull'indirizzo e-mail e su una password.

    Per creare una scrematura degli indirizzi e-mail validi si può ricorrere alla funzione ereg() per verificare che l'indirizzo sia quantomeno verosimile.

    Traggo spunto dal sito della Wrox con un esempio pratico di validazione di un' e-mail
    codice:
    <?php
    //email_check.php
    
    function emailcheck($intext) {
       $theresults = ereg("^[^@ ]+@[^@ ]+\.[^@ \.]+$", $intext, $trashed);
       if ($theresults) { $isamatch = "Yes"; } else { $isamatch = "No"; }
       echo("E-mail address check for \"$intext\": $isamatch
    \n");
    }
    
    emailcheck("ImaUser18523");
    emailcheck("ImaUser18523@ola.com");
    emailcheck("Bogus User@bigmailhost.com");
    emailcheck("Bogus@User@2@bigmailhost.com");
    emailcheck("joebeer62432@somehost.com");
    
    ?>
    Solo la 2a e la 5a vengono validate

    Questo esempio sembra complicato... a prima vista. Ma se scomponete in pezzi la struttura di ereg() vedrete che non è poi così complicato. Chiaramente queste sono indicazioni su come validare una stringa prima di passarla alla query ma rende l'idea di quello che si può fare manipolando i dati prelevati dai form.
    Spero sia utile a qualcuno!

    Ciao e alla prossima
    Slack 10 - Apple G5 2.5 - winzoz xp
    php/mysql/apache
    Flash MX / roba in 3D / roba per il video e l'audio

  3. #3

    Re: SECONDA PARTE

    Originariamente inviato da flessciato
    Per creare una scrematura degli indirizzi e-mail validi si può ricorrere alla funzione ereg() per verificare che l'indirizzo sia quantomeno verosimile.

    Traggo spunto dal sito della Wrox con un esempio pratico di validazione di un' e-mail
    wow ... che bell' esempio

    questa passa

    emailcheck(".@..!");

    e come quella ne passano altri 10000 di fake ...


    ereg, eregi , sono lenti e poco potenti, consiglio a chi vuole usare le espressioni regolari di usare le pregs

    mentre per il controllo email consiglio sempre questa, usata da molti e probabilmente una delle meno permissive ...

    codice:
    function checkMail( $m ) {
    	// andr3a / HTML.IT
    	$r = "([a-z0-9]+[\._\-]?){1,3}([a-z0-9])*";
    	$r = "/(?i)^{$r}\@{$r}\.[a-z]{2,6}$/";
    	return preg_match($r, $m);
    }
    il link con eventuali e futuri aggiornameti
    http://www.devpro.it/php4_id_2.html

    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  4. #4
    Utente di HTML.it L'avatar di flessciato
    Registrato dal
    Jun 2002
    Messaggi
    1,522
    certo, ne passano molte altre... l'esempio è embrionale. Passano anche le mail che finiscono con .con invece che con .com se è per questo e non viene fatto un controllo preciso. Bisognerebbe aggiungere un array etc etc etc...

    Il mini tutorial era per spiegare l'utilizzo (partendo da cose molto semplici) dei termini chiave delle funzioni

    ([a-z0-9]+[\._\-]?){1,3}([a-z0-9])

    questo io e te sappiamo cosa vuol dire... ma non lo sanno tutti :-)

    Integra piuttosto (se hai tempo) la costruzione di stringhe diricerca più complesse con molti esempi (partendo sempre da cose semplici)

    PS: il tuo esempio è fico...
    Slack 10 - Apple G5 2.5 - winzoz xp
    php/mysql/apache
    Flash MX / roba in 3D / roba per il video e l'audio

  5. #5
    Originariamente inviato da flessciato
    Il mini tutorial era per spiegare l'utilizzo (partendo da cose molto semplici) dei termini chiave delle funzioni
    non volevo togliere niente a questa pillola, va benissimo, solo che e' argomento trattato anche in un articolo e in un'altra pillola e in generale volevo consigliare, una volta fatti i primi tests o una volta capitone il funzionamento, di usare preg_match, preg_match_all, preg_replace ... le pregs insomma



    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  6. #6
    codice:
    function checkMail( $m ) {
    	// andr3a / HTML.IT
    	$r = "([a-z0-9]+[\._\-]?){1,3}([a-z0-9])*";
    	$r = "/(?i)^{$r}\@{$r}\.[a-z]{2,6}$/";
    	return preg_match($r, $m);
    }
    Ho provato questa funzione!! E' ottima, ma facendo delle prove mi permetterei di far notare che:

    - la regola $r applicata anke dopo il punto permette di inserire uno di questi tre caratteri [\._\-]? ed opzionalmente terminare con uno o + caretteri alfanumerici ([a-z0-9])* quindi se scrivo info@miodominio_aa_aa_.it lo accetta e penso che non sia valido.

    - mi sono permesso di modificarla così :
    codice:
    function checkMail( $m ) {
    	// andr3a / HTML.IT
    	$r = "([a-z0-9]+[\._\-]?){1,3}([a-z0-9])*";
    	$rdominio = "([a-z0-9]+[\._\-]?){1,3}([a-z0-9])+";
    	$r = "/(?i)^{$r}\@{$rdominio}\.[a-z]{2,6}$/";
    	return preg_match($r, $m);
    }
    Nulla a togliere a nessuno di voi che siete fantastici , ma poiche' stamane mi sono svegliato col proposito di impapare le espressioni regolari, sono praticamente impazzito nel comprendere il codice di andr3a ....

    Spero di non aver offeso nessuno
    ______________________________________

    Progresso Web.

  7. #7
    Originariamente inviato da caruccis
    - la regola $r applicata anke dopo il punto permette di inserire uno di questi tre caratteri [\._\-]? ed opzionalmente terminare con uno o + caretteri alfanumerici ([a-z0-9])* quindi se scrivo info@miodominio_aa_aa_.it lo accetta e penso che non sia valido.
    hai ragione, non ci avevo mai pensato ... cmq l'intento e' di scoraggiare a scrivere emails non valide, non e' una funzione assoluta o risolutrice, questo solo per dirti che non devi fare mai affidamento su un controllo in sola preg soprattutto con dati come emails o siti


    Originariamente inviato da caruccis
    - mi sono permesso di modificarla così :
    codice:
    function checkMail( $m ) {
    	// andr3a / HTML.IT
    	$r = "([a-z0-9]+[\._\-]?){1,3}([a-z0-9])*";
    	$rdominio = "([a-z0-9]+[\._\-]?){1,3}([a-z0-9])+";
    	$r = "/(?i)^{$r}\@{$rdominio}\.[a-z]{2,6}$/";
    	return preg_match($r, $m);
    }
    Nulla a togliere a nessuno di voi che siete fantastici , ma poiche' stamane mi sono svegliato col proposito di impapare le espressioni regolari, sono praticamente impazzito nel comprendere il codice di andr3a ....

    Spero di non aver offeso nessuno
    nessuna offesa ma devo contraddirti per questa funzione ... i domini possono avere solo caratteri alfanumerici ed un trattino:
    http://www.nic.it/RA/domini/regole.html


    ergo grazie per la segnalazione, verrai incluso nell' header di questa nuova versione
    (che non e' comunque perfetta con le regole per i domini, vedro' se migliorarla ancora)
    codice:
    function checkMail( $m ) {
    	// andr3a / HTML.IT / caruccis
    	$r1 = "([a-z0-9]+[";
    	$r2 = "\-]?){1,3}([a-z0-9])*";
    	return preg_match("/(?i)^{$r1}\._{$r2}\@{$r1}{$r2}\.[a-z]{2,6}$/", $m);
    }
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

  8. #8
    grazie per l'attenzione
    ______________________________________

    Progresso Web.

  9. #9
    Originariamente inviato da caruccis
    grazie per l'attenzione
    grazie a te per la segnalazione
    Formaldehyde a new Ajax PHP Zero Config Error Debugger

    WebReflection @WebReflection

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.