Nie generuj kodu!

Samodzielne generowanie kodu jest przyczyną wielu problemów i niepowodzeń (szczególnie mało doświadczonych programistów, ale nie tylko). Przez generowanie kodu rozumiem tutaj pisanie programu, który wygeneruje drugi program (być może w innym języku), a potem go użyje. Przykład, z którym spotkało się chyba najwięcej osób to generowanie zapytań SQL w ten sposób:

$query = "SELECT * FROM foobar WHERE id = " . $id;

Jakie problemy powoduje generowanie kodu?

Najczęstsze problemy z generowaniem kodu:

  • brak/niepoprawne czyszczenie danych ze znaków specjalnych (escape)
  • błędy związane z kodowaniem znaków
  • błędy semantyczne (wygenerowany kod się nie parsuje)
  • błędne kodowanie wartości specjalnych (np. null, true, false)

Przykładowe konsekwencje:

  • bezpieczeństwo:
    • SQL Injection
    • XSS
    • wstawianie HTML do kodu, w którym powinien być tylko tekst
    • itp.
  • poprawność:
    • aplikacja nie działa
    • aplikacja się rozsypuje graficznie
    • aplikacja działa ale niepoprawnie
  • spójność danych:
    • utrata danych
    • błędy w komunikacji z serwerem z danymi
    • błędy w komunikacji po API

Kiedy generujesz kod

Bardzo dużo osób generuje kod nie do końca zdając sobie z tego sprawę. Przykłady:

generowanie html

<h1><?php echo $title ?></h1>
$("<h1>" + title + "</h1>")

generowanie SQL

$query = "SELECT * FROM foobar WHERE id = " . $id;

generowanie zapytań jQuery

$("h1[data-id=" + id + "]")

generowanie JSONa

print "{ value: %d }" % (value)

Rozwiązania

Nie generowanie kodu

W niektórych przypadkach można nie generować kodu po prostu rozwiązując problem inaczej. Np. powyższe zapytanie jQuery:

$("h1").filter(function() {
    return $(this).data('id') == id;
})

Generowanie kodu poprzez bibliotekę, która robi to od początku do końca

Przykład z JSON:

print json.dumps({"value": value})

Dla SQL był by to ORM.

Wsparcie się w generowaniu kodu

To najgorsze rozwiązanie, ponieważ z reguły nie gwarantuje poprawności. Jednak jest to lepsze niż nic (zabezpiecza przez dużą częścią problemów).

<h1>{{ title }}</h1>
some_lib_call("SELECT * FROM foobar WHERE id = ?", $id);

Podsumowanie

Jeśli już musisz generować kod używaj do tego przeznaczonych narzędzi, nie rób tego nigdy sam/a. A jeśli już naprawdę chcesz generować kod skończ kurs (lub przeczytaj porządną książkę) dotyczący semantyki programów. Dopiero wtedy będziesz rozumieć na co się piszesz (generowanie poprawnego kodu nie jest łatwe).

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

*

Możesz użyć następujących tagów oraz atrybutów HTML-a: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">