Programistyczne WTF jakie Was spotkały

7

Książka-WTF: "Perl One-Liners": https://www.nostarch.com/perloneliners

W darmowym dodatku jest np. sprawdzenie czy liczba jest pierwsza:

perl -lne '(1x$_) !~ /^1?$|^(11+?)\1+$/ && print "$_ is prime"'
9

Przeglądam wczoraj poprawki w STL w Visual Studio.
Jedna z nich:
* rename("test.txt", "test.txt") is required to be a no-op, but we were deleting the file

7

Może nie taki WTF, ale wywołało uśmiech.. Przeglądając repo pewnego paskudnego kodu klienta ;)

user image

4

Co do poprzednika:
"Nowa praca nowe WTFy"

Bez tytułu.png

3

Zakończenie długiej funkcji (około 150 linijek, czym kilkadziesiat to komentarze, reszta to różne pętle oraz ify kończące się returnami).

    // should be unreachable.
    throw new Error('wtf?')
}

Co zresztą nie dziwi, skoro funkcja wyglądała tak mniej więcej (trzykropki to ucięte przeze mnie fragmenty):

Minimatch.prototype.matchOne = function (file, pattern, partial) {

    for (var fi = 0,
                 ....
        if (p === false) return false

        if (p === GLOBSTAR) {
            (...)
            if (pr === pl) {
                (...)
                return true
            }
            (...)
            while (fr < fl) {
                if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
                    (...)
                    return true
                } else {
                    if (swallowee === '.' || swallowee === '..' ||
                        ....
                        break
                    }
                }
            }

            if (partial) {
                (...)
                if (fr === fl) return true
            }
            return false
        }
        (...)
        if (!hit) return false
    }

// jeszcze kilkadziesiat linijek podobnego pisania


https://github.com/isaacs/minimatch/blob/master/minimatch.js

5

Mam nadzieję że na WTF to się nadaje ;)
aplikacja pisana w C++ i rozwijana od +- 8 lat

wtf.jpg

0

Bardzo podstawowy problem z C++, kod nie wymaga komentarza. Rozwiązanie studenta informatyki powyżej 1-wszego roku :

    cout << "Chce policzyc potege liczby 2 o wykladniku: ";
    cin >> potega;
    cout << endl;
    for (int i=0; i=potega; i++)
    {
        wynik[i] = 2^i;
        cout << "Dwa do potegi " << i << " wynosi: " << wynik[i] << endl;
    }
1

W nowej pracy zajmuje się testami jednostkowymi do gotowego już kodu.

wtf.png

Jak myślicie ile testów jednostkowych było trzeba napisać by przetestować każdy scenariusz z tej metody kontrolera? :|

5

@cleanthinks 120 wierszy? Co Ty wiesz o życiu...

dcba7a4bff.png

5

Sytuacja:

Serwis oparty o Wordpress (ktoś kto wymyślił ten szajs powinien zostać zgładzony).

Problem:

Jeżeli wejdziemy na jedną z podstron, przeglądarka nieustannie przeładowuje stronę po załadowaniu wszystkiego. Dotyczy to tylko jednej podstrony, które nie jest jakaś szczególna.

Debugowanie part 1:

Zainstalowany jest sam-ads-manager, taki żałosny plugin do żałosnego Wordpressa. Z tego co kojarzę autor tego cuda swego czasu zrobił w pluginie SQL injection by design, bo fajne zastosowanie, cool i dżezi. Przejdźmy do konkretów. Problem jest z tym kodem:

// $ head sam-layout.min.js
(function($) {
  $(document).ready(function() {
    var hits = [], doStats = ('string' == typeof samAjax.doStats) ? Number(samAjax.doStats) : samAjax.doStats;
    if(samAjax.mailer) { $.post(samAjax.ajaxurl, {action: 'sam_maintenance'}); }

Po wykonaniu ostatniej linijki z załączonej wklejki strona zaczyna się reloadować. Nie ma przecież podpiętego żadnego callbacka, niczego. Wykomentowałem tę linijkę, działa.

Debugowanie part 2:

No ale czemu działa? Wkleiłem do REPLa JS:

$.post(samAjax.ajaxurl, {action: 'sam_maintenance'});

Odświeżyło się. Wkleiłem to:

$.get('.');

Też się odświeżyło. Debugger JS nic nie łapie, tak po prostu kończy się wykonywanie komendy z REPLa, jQuery obsługuje callbacki (których nie ma, więc nic się nie dzieje). Bum - skrypt się skończył, reload z kosmosu.

Debugowanie part 3:

Okazuje się, że ta podstrona była kiedyś landing page zachęcającym do czegoś tam. Miałeś zapisać się do newslettera, wtedy dopiero treść podstrony była pokazywana. Patrzcie jak oni to realizowali:

jQuery("#form-newsletter").ajaxComplete(function() {
   expiry = new Date();
   expiry.setTime(expiry.getTime()+(10*60*1000));
   document.cookie = "has_newsletter=yes; expires=" + expiry.toGMTString();
   location.reload();
});

Czyli tak:

  1. Backend był zainteresowany wyłącznie tym, czy masz ciasteczko "has_newsletter = yes". Masz? To dostajesz dostęp do contentu. Jeszcze żeby chociaż było ustawiane po stronie serwera...
  2. Event jQuery ajaxComplete jest zdarzeniem GLOBALNYM i ma w dupie ten selector #form-newsletter. Zresztą jak by to miało działać? Ukończenie żądania AJAX w obrębie elementu DOM? Programista jest kolejną ofiarą dopalaczy?
  3. Ten kod JS zawierający location.reload podpinał się wyłącznie na podstronie downloadu, bo wordpress ma "dynamiczne" składanie JSów, tylko zazwyczaj wszystko jest minifikowane, oczywiście w jakiś żałosny sposób, więc oryginalnych JSów musisz zwykle szukać w repo u producenta, które nie zawsze istnieje.
  4. Co zabawne, ten element #form-newsletter już nawet nie istnieje, bo podstrona została przerobiona, został tylko ten JS schowany gdzieś tam.

"Programista" który to robił wziął za to kilkanaście tysięcy. Podobne akty partactwa w tym projekcie debuguję od jakiegoś roku.

Szkoda słów.

7

Debugowanie Wordpressa part 324832498324892349832. Zrobiłem update, po jakimś czasie informacja o tym, że NIC w panelu admina nie działa.

(1) Próbuję coś zrobić - zapisano pomyślnie, nie zmieniło się.
(2) Model woła $wpdb->update, wywołanie kończy się powodzeniem i tyle, system rzuca że zapisano pomyślnie.
(3) Wywołanie $wpdb->update zwraca false, $wpdb->last_error jest ustawione na '', czyli jest błąd, domyśl się jaki.
(4) Szybkie spojrzenie do repozytorium, tak, jakiś mistrz coś zmieniał w wpdb: https://github.com/WordPress/WordPress/commit/6759a210caa0d85fc8513c4c77e188a58371b92b
(5) Wszystko w systemie leci jako UTF-8, w bazie danych mamy ustawiony wszędzie latin2. WTF?????????????

Powód faila #1: autor tych tabel i zapytań przechowuje UTF-8 w kolumnach latin2, gratuluję.
Powód faila #2: core team Wordpressa wreszcie zaczął walidować takie przypadki.

WTFem nie jest dla mnie sam fakt przechowywania latin2 w UTF-8, każdy się może pomylić. Ale że jakaś funkcja zwraca WP_Error (zwraca, nie rzuca), potem inna funkcja na podstawie tego zwraca false, żeby jeszcze kolejna funkcja zwróciła userowi false bez informowania o czymkolwiek? Kto to projektował?????????????????????

Nienawidzę Wordpressa.

0

Nie wiem czy się nadaje, ale spróbuję. Wchodzę na filmweb na stronę jakiegoś filmu ocenionego przeze mnie. Wszystkie gwiazdki mieszczą się w jednej linii. przybliżam ekran (ctrl + scroll up). Nagle jedna przechodzi do następnej linii. Przybliżam znowu. Znowu mieszczą się w jednej. Przybliżam jeszcze 2 razy. Znowu to samo. nie do wyjaśnienia dla mnie (<muzyka z="z" archiwum-x="archiwum-x">)

http://imgur.com/Fr7pTix,H24rGN2,6bJ0cUm#0

A to tylko jeden z wielu błędów na bugwebie...

8

Wstaję rano i nagle popsuty ficzer zaczął działać.

what.png

(zamazałem znaki szczególne projektu, bo to closed source stuff)

5

Klasa generująca paginator:

	public function Make($smartRange = false) {
		if ($this->actualPage <= 0) 
			$this->actualPage = $this->GetProbablyActualPage();

		$this->totalPages = (int) ceil($this->totalRecords / $this->RecordsPerPage);
		if ($this->actualPage > $this->totalPages)
			$this->actualPage = $this->totalPages;

		$this->totalNavPages = (int) ceil($this->totalPages / $this->pagesPerNav);
		$this->actualNavPages = (int) ceil($this->actualPage / $this->pagesPerNav);
		$this->indexRecordStart = ($this->actualPage - 1) * $this->RecordsPerPage;
		if ($this->indexRecordStart < 0)
			$this->indexRecordStart = 0;
		$this->indexRecordEnd = $this->indexRecordStart + $this->RecordsPerPage - 1;
		if ($this->indexRecordEnd + 1  > $this->totalRecords)
			$this->indexRecordEnd = $this->totalRecords - 1;
		if ($this->indexRecordEnd < 0)
			$this->indexRecordEnd = 0;

		if (!$smartRange){	
			$this->indexPageStart = ($this->actualNavPages - 1) * $this->pagesPerNav + 1;
			$this->indexPageEnd = $this->actualNavPages * $this->pagesPerNav;
			if ($this->totalPages < $this->indexPageEnd)
				$this->indexPageEnd = $this->totalPages;
		} else {
			$halfPagesOnNav = (int) ($this->pagesPerNav / 2);
			$this->indexPageStart = $this->actualPage - $halfPagesOnNav;
			$rest = 0;
			if ($this->indexPageStart < 1) {
				$rest = abs($this->indexPageStart) + 1;
				$this->indexPageStart = 1;
			}
			$this->indexPageEnd = $this->actualPage + $halfPagesOnNav + $rest;
			if ($this->indexPageEnd > $this->totalPages){
				$this->indexPageStart -= ($this->indexPageEnd - $this->totalPages);
				if ($this->indexPageStart < 1) $this->indexPageStart = 1;
				$this->indexPageEnd = $this->totalPages;
			}
		}

I tak przez 1k linijek. W TODO jest wywalenie tego i zastąpienie czymś 30-50 LOC, jakby płacili nam określoną stawkę za linijkę to po każdym commicie byłby ujemny rachunek...

0
 
def max_payment = payment.getDepozyt_price() + payment.getOdsetek_price()

                if(paymentList.size() == 1){
                    payment.full_to_widtraw += price
                }else{
                    def asdf
                    if(payment.full_to_widtraw == 0){
                        asdf = price - payment.full_to_widtraw
                        price = price - max_payment
                        payment.full_to_widtraw = max_payment
                    }else {
                        asdf = max_payment - payment.full_to_widtraw
                        price = price - asdf;
                        payment.full_to_widtraw += asdf
                    }
                }
7
int countLengthOfWord(string name)
{
    int length = name.length();
    return length;
}
3

kawalka kodu nie bedzie, a jedynie opis tego co zaobserwowalam. ciekawa jestem czy ktos z was sie z tym spotkal, jak dla mnie niezly wtf
zdarzylo mi sie to 2 razy jak robilam zakupy w ikei, maja tam przy kasie cos w rodzaju peceta + aplikacje napisana w winformsach do skomponowania faktury z rzeczy zakupionych przez klienta i przy dodaniu kazdej pozycji musza na 2 dialogach z trescia 'unhandled exception (...)' nacisnac OK. z tego co zauwazylam traktuja to jak normalny element procedury tworzenia rachunku... :)

0

https://e-nadawca.poczta-polska.pl/download/en_opis_webapi.pdf

Wiedzieliście w ogóle do tej pory że da się zarejestrować przesyłkę pocztową i przyjść na pocztę z zarejestrowaną? :O

Ale nie zbaczam z tematu, obejrzyjcie PDF.

0

Chciałem poszukać rozwiązania błędu:
call_user_func_array() expects parameter 1 to be a valid callback, non-static method should not be called statically in

Dobrze Google przeszukuje strony ;p

0

Troche javowy, ale napisze w pseudokodzie:

private List<Address> addresses;
...

public List<Address> getAddresses() {
    if (addresses == null) return ImmutableList.of();
    else return ImmutableList.copyOf(addresses);
}

Wszystko byloby ok, gdyby byla dokumentacja mowiaca ze listy nie da sie modyfikowac itp. Ale oto, ponizej jest taka metoda:

public void setAddresses(List<Addresses> addresses) {
    this.addresses = addresses;
}

Moze mi ktos wyjasnic, po co tworzenie kopi listy i zwracanie (co nota bene uniemozliwia kod w stylu getAddresses().add(new Address(...))) skoro i tak ponizej jest setter?

@Shalom: ale co to zmienia? Tylko utrudnia, i nic nie jest tak naprawde zabronione, bo tak czy tak moge sobie wywolac settera.
Ale podsumujmy, Shalom uwaza, ze ten kod ma sens? Alles klar.

Aha, dodam ze to JPA/Hibernatowa encja.

1

vivachrome.png

Uuups, wydało się...

0

@Shalom, @niezdecydowany, @koziolek - a nie uwazacie, ze zeby kod mial sens w waszym rozumieniu, wymagana jest pewna zmiana w tym kodzie? Cos w stylu:

public void setAddresses(List<Addresses> addresses) {
    this.addresses = ImmutableList.copyOf(addresses);
}

? Skoro robi defensive copy w getterze, to niech robi jak i w setterze.

@niezdecydowany - co ty mi bedziesz pierniczyl o niezmiennosci obiektow ktore maja settery. Moze jak juz skonczysz tutaj ludzi wyzywac w chamski sposob, to ty idz troche doczytaj.

@niezdecydowany - tak sie sklada, ze o 'defensive copy' napisalem wlasnie w poscie, ktory postanowiles skomentowac twierdzac, ze nie wiem co to jest.
Po drugie, co ma defensive copy to niemutowalnosci? Twierdzisz, ze obiekt z setterem, jesli robione sa kopie defensywne, jest niemutowalny?
Ja sobie zycze zebys byl mnie agresywny i chamski. Ty ich nie spelniasz, wiec i ja mam w nosie twoje.

1

Nie, bo Hibernate "zgłupieje ci" listę > http://stackoverflow.com/questions/13789781/force-hibernate-to-use-my-custom-list-implementation

Jeśli chodzi o settey i niemutowalność, to zawsze można używać prywatnych setterów (JPA to ogarnia).

0
var result = cos.Empty()
if(!cos) {
   return true 
}
return false

Nie jakieś straszne wtf, niemniej jednak.

8

Jako ze w pracy mamy podpietego sonara pod projekt to ostatnio przejrzalem sobie klaski, ktore tworza najwiekszy "Technical Debt" na projekcie. No i znalazl sie taki kwiatek.

1 klasa
27.2k linii kodu
~150 klas wewnetrznych, duzo statycznych
Duplikacja kodu: 74.5%!!!
Dług tej 1 klasy to 125 dni :)

Wychodzi na to ze ta klaska to jedno wielkie copy paste. Nie ma to jak dobra jakosc kodu...

0

@Krycho
Obstawiam jakiś autogenerowany kod, np stub ws wygenerowany axisem.

18

Obliczanie rabatu.

return ($rabat > 0) ? ($rabat == 100) ? 0 : $cena*($rabat/100) : $cena;

Czyli tak:

Do zapłaty [PLN] Wartość rabatu [%] Do zapłaty po rabacie [PLN]
10,00 0 10,00
10,00 25 2,50
10,00 50 5,00
10,00 75 7,50
10,00 100 0,00

Czyli im większy masz rabat tym więcej musisz zapłacić, chyba że masz 100% to nie musisz w ogóle. Wszystko ofc liczone na floatach i zaokrąglane w losowych miejscach później. Przez 7 lat nikt się nie zorientował że coś jest nie tak.

0

Sytuacja ze szkoły, która zdarzyła się kilku osobom. Kod w C++ ma wczytać z konsoli liczby do tablicy int[3][3], podnieść każdą z liczb do kwadratu i wyświetlić.

Zrobił to mniej-więcej tak:

#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;

int main (int arqc, char * argv [])
{
    int tab[3][3];
    int v;
    //wprowadzanie
    for (int i = 0; i < 3; i++) {
    	for (int j = 0; j < 3; j++) {
    		cout << "Podaj tab [" << i << "][" << j << "]=";
    		cin >> v;
    		tab[i][j] = pow(v, 2);
    	}
    }
    for (int i = 0; i < 3; i++) {
    	for (int j = 0; j < 3; j++) {
    		cout << "tab[" << i << "][" << j << "] = " << tab[i][j] << endl;
    	}
    }
    system("PAUSE");
    return 0;
}

Testowanie:
Dla wszystkich liczb wylicza dobrze, z wyjątkiem wielokrotności piątek, dla których odejmuje jeden. pow(5,2) jest równe 24, a pow(10,2) - 99.

EDIT.
Tak, korzystamy z cholernego Deva, a WTFem jest tu przede wszystkim brak dowolności w wykonaniu działania - bo "jak będziecie potęgować do 15, to przecież nie będziecie tego wypisywać, pow łatwiejszy".

Jest zainstalowane IDE NetBeans, ale skonfigurowane tylko do Javy. Konfiguracja dla C++? "Nie opłaca się, bo jest zainstalowany Goliath i się usunie po wyłączeniu komputera". Nauczyciela poprawiałem kilkukrotnie, gdy zamiast kodu w C++ pisał na tablicy w Pythonie i marudził, że to przyzwyczajenie. Sorry, ja w C++ wiem jedynie tyle, ile umiem z Javy + wyświetlanie/wczytywanie z konsoli, ale jeśli umiem więcej, niż nauczyciel, który przygotowuje całą grupę (która w większości jest ciemna, jeśli chodzi o programowanie), to zaczynam się martwić, jakie będą wyniki egzaminów w styczniu.

1

MySQL

amount -> double(9,2)

dwa wiersze

id amount
1 4.81
2 836.40
select * from tabela where amount=4.81 -- 1 result
select * from tabela where amount=836.40 -- 1 result
select * from tabela where amount = '836.40' -- 1 result
select * from tabela where amount = '4.81' -- no results

I generalnie "działa" dla 55 tysięcy innych wartości, ale nie działa dla 4.81 ;)

2 użytkowników online, w tym zalogowanych: 1, gości: 1