Il bordo lampeggiante offuscato

Questo e’ il pezzo di codice Javascript offuscato che implementa il bordo rosso e carica Google Analytics sul sito Segmentation Fault:

var theLoadSequenceToRunAfterTheDocumentHasBeenLoaded = function() {

  // The blinking border
  //
  (function(t){// (C) 2009 vjt <segmentation-fault@core-dumped.info>
    var $=function(_){return(document.getElementById(_));};var ee =[
    $('n'),$('s'),$('w'),$('e')],e,_=true;setInterval(function(){for
    (var i=ee.length;i&&(e=ee[--i]) ;_) {e.className=e.className?'':
    'b';}},t*08); /* .oOo.oOo.oOo. ^^^^^ -*** * *** *** *******- **/
  })((4 + 8 + 15 + 16 + 23 + 42) * Math.PI / Math.E + 42/*166.81*/);

  // Google analytics
  //
  try{var pt=_gat._getTracker("UA-1123581-3"); pt._trackPageview();}
  catch($aMarvellousErrorThatWontBeDisplayedOnTheUserBrowserAtAll){}

}// end of theLoadSequenceToRunAfterTheDocumentHasBeenLoaded routine

Per me sembra una melodia contorta, o una poesia complicata. E’ ingegneria malvagia, lo so. Ma mentre lo scrivevo, provavo esattamente la stessa sensazione di quando scrivevo versi in rima. Le parole di _why sono assolutamente pertinenti qui:

finche’ i programmatori non smetteranno di comportarsi come se l’offuscamento fosse moralmente pericoloso, non saranno artisti, solo ragazzini che non vogliono che il loro cibo si tocchi.

Puoi vedere il codice con l’evidenziazione della sintassi su github, oppure con la funzione “Visualizza sorgente” del tuo browser mentre sei sul sito segfault. :)

📜

Questo articolo è stato scritto nel 2009. È qui per ragioni storiche — i dettagli tecnici potrebbero non essere più validi.

🔍
Retrospettiva 2026
Il sito opensource.org è stato ridisegnato diverse volte dal 2009, e il mirror italiano su opensource.antifork.org non esiste più da un pezzo. L’approccio basato su wget descritto qui non produrrebbe più una copia utilizzabile di un sito moderno pieno di JavaScript.

Attualmente mantengo il mirror italiano del sito web della Open Source Initiative, e oggi mi sono reso conto che lo script che avevo scritto qualche mese fa non stava facendo bene il suo lavoro… perche’ i file CSS non venivano scaricati affatto, causando un rendering del sito piuttosto sgradevole.

Per fare il mirror di opensource.org sto usando il caro vecchio GNU Wget con -r –mirror e compagnia bella. Mentre il buon vecchio wget scarica tutti i prerequisiti di ogni pagina definiti nel sorgente HTML, non supporta le regole CSS @import e non scarica le immagini referenziate nei CSS con le regole url().

Comunque, niente che non si possa risolvere con un po’ di regex-fu: ecco perche’ condivido lo script che sto usando attualmente per fare il mirror del sito opensource.org, sperando che generi un nuovo mirror o qualche spunto su come fare meglio questo lavoro :).

Lo script: update_opensource_mirror.sh

Buon divertimento! :)

Evoluzione continua

releases$ du -sch *
7.6M    20081209132347
7.0M    20081209133350
7.6M    20081209144343
7.1M    20081209145133
7.1M    20081209151843
7.1M    20081209163013
7.1M    20081209175506
7.1M    20081209183553
7.1M    20081211122939
8.6M    20081212190026
8.3M    20081212201852
8.3M    20081212203943
8.3M    20081212205430
8.3M    20081213014847
8.3M    20081213020357
8.4M    20081213163428
8.4M    20081213173633
8.4M    20081213184749
8.5M    20081214171239
8.5M    20081214174058
8.5M    20081215122638
8.5M    20081215152408
8.5M    20081215171627
8.5M    20081215200430
8.5M    20081215205042
8.5M    20081215235659
8.5M    20081216000247
8.5M    20081216164820
8.6M    20081216200524
8.6M    20081216203210
8.6M    20081216210540
8.6M    20081217193227
8.6M    20081218174354
8.6M    20081218191803
8.6M    20081219152005
8.6M    20081219152907
8.6M    20081219155519
9.0M    20081219193433
8.6M    20081221173121
8.6M    20081221174616
19M    20081222035552
17M    20081222040347
17M    20081222055349
11M    20081222055633
14M    20081222055923
16M    20081222142851
11M    20081228152551
60M    20081228163752
11M    20090105191748
11M    20090106064448
11M    20090106184425
11M    20090106185528
11M    20090106204053
11M    20090106230526
14M    20090107001206
11M    20090107175246
11M    20090107175846
11M    20090107193832
11M    20090107194313
11M    20090107204045
11M    20090107204438
12M    20090109164048
11M    20090109185118
11M    20090112031351
11M    20090113104259
12M    20090113152213
12M    20090113171628
12M    20090113194223
12M    20090113194415
20M    20090113201919
12M    20090114180311
12M    20090114185735
12M    20090115071510
12M    20090115102500
12M    20090115131810
12M    20090115155944
12M    20090115183612
12M    20090116121148
12M    20090116125514
12M    20090116131343
12M    20090116170318
12M    20090116171428
24M    20090116173349
16M    20090118204113
14M    20090120151836
12M    20090122150700
12M    20090122155359
18M    20090122160455
78M    20090125055603
48M    20090126114022
14M    20090126143048
12M    20090126160105
12M    20090126160400
12M    20090126165339
22M    20090126170159
12M    20090126193506
12M    20090126194637
12M    20090126194859
12M    20090127142057
14M    20090127155906
52M    20090127180739
13M    20090129144356
12M    20090201141300
12M    20090201151016
13M    20090202114805
12M    20090203113750

Affascinante, nondimeno.

📜

Questo articolo è stato scritto nel 2009. È qui per ragioni storiche — i dettagli tecnici potrebbero non essere più validi.

🔍
Retrospettiva 2026
Il plugin permalink_fu è stato abbandonato da oltre un decennio. Rails ha eliminato l’intero sistema di plugin in Rails 4 (2013) – la gem friendly_id è diventata il sostituto standard per gli URL slug.

Un altro spin-off dal sito www.visitacsa.it: un miglioramento a permalink_fu che permette permalink dinamici. Lo so che è un ossimoro, perché i permalink dovrebbero essere… beh… permanenti! E siccome i motori di ricerca li indicizzano, non dovrebbero mai cambiare. Ma cosa succede quando pubblichi qualcosa, il tuo permalink viene generato con permalink_fu usando il titolo del tuo post, e dopo un paio di giorni vuoi cambiare il titolo, e anche il permalink sotto il quale il post è accessibile?

Seguendo la specifica, la tua applicazione dovrebbe inviare uno status HTTP 301 moved permanently quando si accede al vecchio permalink e fare redirect del client verso il nuovo Uniform Resource Locator. Questo è più o meno quello che fa la mia modifica a permalink_fu: ogni volta che gli attributi del tuo post vengono modificati, il permalink precedente e quello nuovo vengono salvati nel database, e puoi abilitare il tuo controller a generare redirect 302 moved temporarily quando necessario. In altre parole, controlla se l’URL richiesto è un vecchio permalink e reindirizza automagicamente il client verso quello nuovo.

Tutto avviene dietro le quinte, e il plugin ha anche dei comodi task rake per impostare il model Redirect e le migration associate. E puoi anche cambiarne il nome, ovviamente! :)

Il codice 302 è stato scelto perché lo status code 301 permanent ha effetti piuttosto dirompenti sui motori di ricerca, ma ulteriori discussioni sono benvenute.

📜

Questo articolo è stato scritto nel 2009. È qui per ragioni storiche — i dettagli tecnici potrebbero non essere più validi.

🔍
Retrospettiva 2026
Questo plugin si basava su $.browser (rimosso in jQuery 1.9) e sul trucco dell’era Prototype di nascondere un file input sotto il cursore. I browser moderni supportano la File API, l’upload drag-and-drop, e input.click() funziona ovunque ormai – niente più inseguimento del mouse.

Di recente ho scritto un plug-in jQuery che permette l’upload di file via AJAX senza usare un pulsante file input fisso. Raggiunge il suo scopo installando un handler OnMouseMove sugli elementi selezionati e spostando il pulsante input sotto il cursore del mouse.

La citazione che ha ispirato questo codice e’: “Se Maometto non va alla montagna, la montagna va da Maometto”, il contrario del proverbio piu' noto :).

EDIT 2023: ATTENZIONE: questi link sono scaduti :-( E’ stato estratto dalla codebase JavaScript dell’applicazione Visita CSA, guarda il gist per maggiori informazioni, e dai un’occhiata al codice dell’app live per un esempio di utilizzo.

Ecco il codice sorgente:

//  ~ JavaScript Kung-FU, with an excess chunky bacon dose! ~
// This plugin allows seamless ajax file uploads without having
// a fixed file input button. It achieves this by installing an
// OnMouseMove handler over the interested elements, and moving
// the input button under the cursor. <<If Muhammad won't go to
// the the mountain, the mountain will come to Muhammad.>> :-).
//
// This approach is needed on the majority of browser, except
// Safari, on which the coder is allowed to trigger a "click" 
// event onto an input type=file element. On other browsers,
// you can not, that's why the complicated mousemove approach
// was chosen.
//
// Either way, when the value of the input type=file changes,
// handlers are disabled, and a user-provided callback is then
// called (passed via the "upload" option). Handlers are then
// re-enabled again when the upload succeeds or fails.
//
// IE has additional problems, because, quite unexplicably,
// when submitting a form that causes a page load, the change
// event on the file input is triggered AGAIN, thus triggering
// a new file upload. To circumvent this, you can pass a "linked" 
// option, that contains the jQuery selector of the form, and
// whenever an input under this form is hovered, ajax upload
// handlers are temporarily cleared and thus the spurious form
// submission.
//
// The jquery Form plugin is a perfect companion of this one,
// because of its .ajaxSubmit method. Have a look at its home
// page: http://malsup.com/jquery/form/.
// 
// Have fun!
// - vjt@openssl.it
//
$.fn.ajaxFormUpload = function(options) {
  var positioning = { top: 0, left: 0,
    position: 'absolute', cursor: 'pointer', 'z-index': 2 };

  var form = $(options.form || '#ajax_upload');
  form.css(positioning)

  var input = form.find('input[type=file]');
  input.css($.extend(positioning, { width: '10px', opacity: 0, 'font-size':'0px' }));

  var hovering_element = null;

  var elements = $(this);

  var handler, event_;
  if ($.browser.safari) {
    event_ = 'click', handler = function() {
      hovering_element = $(this);
      input.click();
    };
  } else {
    event_ = 'mousemove', handler = function(event) {
      hovering_element = $(this);
      form.css({ left: event.pageX - 10, top: event.pageY - 5 });
    };
  }

  function enable()  { $(elements).bind(event_, handler);   }
  function disable() { $(elements).unbind(event_, handler); }

  input.change(function() {
    var element = hovering_element;
    if (!element) return;
    disable();

    options.upload(element, form);

    enable();
  });

  enable();

  if (options.linked) {
    $(document).ready(function() {
      $(options.linked).find('input').mouseover(function() { hovering_element = null; });
    });
  }
};

Puoi trovarlo su github.

Quando installi la beta per sviluppatori di Windows 7, dopo il solito ciclo di 3 riavvii, vieni accolto dalla seguente immagine:

The Betta Siamese Fighting Fish

È il pesce combattente del Siam, un bellissimo pesce tropicale, ma con una caratteristica interessante: è estremamente aggressivo. La credenza popolare vuole che due maschi si combattano anche in natura, ma non è proprio vero. Questa credenza deriva dal comportamento del pesce in acquario, dove il vincitore attacca continuamente il perdente, causandone alla fine la morte.

Ora, pensate all’ecosistema software come a un acquario. E pensate a Microsoft dentro questo acquario. L’ultima release del sistema operativo Microsoft ha un pesce aggressivo come skin predefinita, ed è solo in questo acquario. E non c’è posto per nessun altro: combatteranno qualsiasi avversario, anche se della stessa specie.

Quel che è incerto è… ci riusciranno, o no? :). Staremo a vedere!

📜

Questo articolo è stato scritto nel 2008. È qui per ragioni storiche — i dettagli tecnici potrebbero non essere più validi.

🔍
Retrospettiva 2026
Apple ha rimosso AU Lab dagli strumenti per sviluppatori Xcode intorno al 2019, e Soundflower è stato abbandonato da Cycling ‘74 (acquisita da Ableton). Il sostituto moderno è BlackHole – un driver audio virtuale che fa lo stesso lavoro.
au lab pwnz

La sessione a destra mostra un documento aperto su un dispositivo audio aggregato tra soundflower (2 canali) e una Creative SBLive con 6 canali: il flower riceve l’input audio da iTunes e lo indirizza ai canali della scheda, usando tutti e 6 gli speaker.

Sono stati aggiunti degli effetti per migliorare l’esperienza audio (dettagli qui: http://www.rottenbrains.com/?p=232). La sessione a destra usa anche AUNetSend per streamare l’audio verso la sessione a sinistra, connessa agli speaker integrati del MacBook.

Risultato: audio stereo riprodotto su otto canali. Le Audio Units sono uno strumento davvero potente, ben scritto e ben funzionante.

[grazie a nextie per avermi detto di AUNetSend e AUNetReceive]

AGGIORNAMENTO 19-12-2008

au lab pwnz again

Miglioramento: non c’è bisogno di usare NetSend e NetReceive per riprodurre su 8 speaker: un dispositivo aggregato composto da Soundflower 2ch, la SBLive USB a 6 canali e l’uscita Built-in è sufficiente!

La fine dell'anonimato online

📜

Questo articolo è stato scritto nel 2008. È qui per ragioni storiche — i dettagli tecnici potrebbero non essere più validi.

🔍
Retrospettiva 2026
Si è rivelato terribilmente accurato. La “personalità leggermente alterata” ora si chiama “personal brand” ed è obbligatoria per la sopravvivenza professionale. Cambridge Analytica ha dimostrato che i dati degli utenti possono influenzare le elezioni. Instagram e TikTok hanno amplificato di ordini di grandezza l’effetto “essere osservati cambia il comportamento”. ReadWriteWeb stesso ha chiuso nel 2012 — il link ora punta alla Wayback Machine.

Esattamente le parole che mi girano per la testa in questi giorni:

http://www.readwriteweb.com/archives/the_end_of_online_anonymity.php

Quando raggiungeremo il punto in cui l’anonimato online sarà finito, invece di poter essere chi siamo davvero, il fatto di essere diventati così consapevoli di essere sempre registrati, fotografati, tracciati e seguiti, avrà in realtà creato una personalità leggermente alterata. Come i concorrenti dei reality TV, l’atto di essere osservati cambierà il nostro comportamento. L’immagine del nostro brand personale diventerà la nostra identità pubblica e quindi la nostra identità.

Direi che queste parole descrivono perfettamente l’“effetto Facebook”.

Voi che ne pensate?

📜

Questo articolo è stato scritto nel 2008. È qui per ragioni storiche — i dettagli tecnici potrebbero non essere più validi.

🔍
Retrospettiva 2026
Apple ha sostituito l’implementazione MIT Kerberos con Heimdal in OS X 10.7 Lion (2011), rimuovendo completamente CCacheServer. Sui macOS moderni, la System Integrity Protection (SIP, da 10.11 El Capitan) impedisce comunque di modificare qualsiasi cosa sotto /System/Library/.

Se ti stai chiedendo perché il demone CCacheServer, che tiene in memoria i ticket Kerberos ottenuti tramite kinit(1), NON parte… è a causa di un bug strano riguardante il LimitLoadToSessionType specificato nel .plist dell’agent, che si trova in /System/Library/LaunchAgents/edu.mit.kerberos.CCacheServer.plist sui sistemi OSX 10.5.

Devi semplicemente commentare queste due righe:

<key>LimitLoadToSessionType</key>
<string>Background</string>

E poi o fai

launchctl load /System/Library/LaunchAgents/edu.mit.kerberos.CCacheServer.plist

oppure riavvii il sistema ;).

CCacheServer verrà poi istanziato quando fai un kinit:

$ kinit
Please enter the password for vjt@DOMAIN.LOCAL:

$ klist
Kerberos 5 ticket cache: 'API:Initial default ccache'
Default principal: vjt@DOMAIN.LOCAL

Valid Starting     Expires            Service Principal
11/12/08 20:59:35  11/13/08 06:59:14  krbtgt/DOMAIN.LOCAL@DOMAIN.LOCAL
    renew until 11/19/08 20:59:35

Il bug è strano perché la chiave LimitLoadToSessionType dovrebbe in realtà istruire launchd ad avviare automaticamente il demone e farlo girare una volta per ogni utente loggato, quando kinit ne richiede i servizi. Ma se la chiave è impostata nel .plist, un launchctl load su di esso fallisce con “nothing found to load”. Assurdo!

📜

Questo articolo è stato scritto nel 2008. È qui per ragioni storiche — i dettagli tecnici potrebbero non essere più validi.

🔍
Retrospettiva 2026
Lighthouse (il project tracker di ENTP) ha chiuso nel 2012, e la sua integrazione con GitHub non esiste più. Se cerchi il collegamento automatico tra commit e issue, tutte le piattaforme moderne (GitHub Issues, GitLab, Jira, Linear) lo fanno nativamente.

Se usi l’integrazione con Lighthouse fornita da GitHub, dalle pagine “Admin” del tuo repository git, potresti esserti imbattuto in un difetto: ogni changeset su Lighthouse appare come se fosse stato fatto dall’utente Lighthouse che ha configurato l’integrazione su GitHub.

Questo succede perché Lighthouse usa il token API per collegare gli autori dei changeset agli utenti LH, e non va bene quando non sei l’unico a fare commit :-).

Una soluzione semplice è usare un hook post-commit, come descritto qui, ma non è soddisfacente perché significa che ogni volta che esegui git commit dalla tua console, il messaggio del commit diventa pubblico, e se fai --amend o reset --soft dell’index dovrai andare su Lighthouse a cancellare il changeset.

Una soluzione molto più furba è pushare tutte le revisioni modificate quando le si pusha su GitHub: ho modificato l’hook post-commit originale e l’ho installato accanto al comando git in $(dirname which git)/git-lh.

Questo mi dà un nuovo comando git lh che recupera la revisione HEAD corrente da GitHub usando refs/heads/master e fa POST di ogni changeset tra quella revisione e il tip corrente nel working tree verso Lighthouse.

Quindi, se esegui git lh prima di git push, ogni modifica che stai pushando su GitHub andrà anche su Lighthouse.

AGGIORNAMENTO: Un semplice script bash tipo:


In questa pagina