Programistyczne WTF jakie Was spotkały

0

Fail z karta miejską jaki ja doświadczyłem w Krakowie.

  1. Płacąc kartą musisz wpisać PIN DWA RAZY!
  2. Jeśli pomylisz się przy wprowadzaniu PIN-u to automat staje się bezużyteczny. Obsługa kart jest realizowana przez osobny moduł (w tej samej obudowie), który ma blokadę na wprowadzanie karty do szczeliny. Na czas kiedy masz się komunikować z tym modułem, główny ekran pokazuje jakąś wiadomość blokującą, jednak gdy, pomylisz się podczas wprowadzania pinu (masz zrobić to dwa razy), to kartę wyciągniesz, ale już jej nie włożysz, a ekran blokady nie zniknie (nadal czeka na realizację płatności) i nie da się nic zrobić (czekałem z 5 minut, ale nic się nie zmieniło).
2

WTF elektroniczne: lampka LED-owa na 230V za 3 złote.
Lampka po podłączeniu okazała się że mruga, w rytm 50-hercowego prądu zmiennego. Myślę sobie, coś schrzanili z prostownikiem.
Rozkręcam, oglądam, i...
... cała lampka jest po prostu mostkiem Graetza zbudowanym na czterech diodach świecących.

0

Takie małe WTF optymalizacji zużycia pamięci...

Siedzę sobie i obrabiam / czyszczę skany rysunków w Gimpie. Skany przy 600 DPI karki A4 - ok 5000x7000px, wszystkie w trybie RGB i takich mam jednocześnie otwartych z 10.
Do tego myzyczka leci w tle z audaciousa - podobne to do winampa
A pomaga mi w pracy firefox - ot 2 zakładki z Profilami kolorów, nic nadzwyczajnego.

Komp zaczyna zamulać - "Oho, pewnie za dużo pootwieranych rysunków. Ale sprawdzę"...
Zużycie pamięci wg htop:
firefox-bin: 65%
audacious: 15%
gimp-2.8: 19%

Moja reakcja: Jakim cudem program graficzny z cięzkimi rysunkami zajmuje mi w pamięci 20% a zwykły odtwarzacz mp3 niewiele mniej? Do tego firefox 19 to super krowa... tylko czemu...

0

C++/WinAPI

Pod jednym przyciskiem zapisuje napisy do dwuwymiarowej tablicy znaków (szNames[64][128] - max. 64 napisy, każdy po max. 128 znaków), a w drugim przycisku odczytuje i dostaje krzaki. Po ponad godzinie zrobiłem szNames zmienną globalną (wcześniej była lokalną w procedurze obsługi okna) i działa.

0

Takie dwa WTF-y, które mi się przypomniały:

  1. spokojnie poprawiam sobie mój kompilator - wszystko działa, generuje poprawny plik wyjściowy - jest perfekt.
    Kompiluję go korzystając z drugiego stopnia optymalizacji (wcześniej było domyślne -O1; kompilowałem korzystając z FPC 2.6.0 na Win32) - i nagle zonk: crash w którejś części mojego parsera.
    Szybki check wszystkiego co mogłoby spowodować taki błąd - kod wygląda dobrze, nie powinno być żadnych null-pointerów itp.
    Wyłączam optymalizacje całkowicie, i znowu crash - tym razem w innej części.
    Zrobiłem wielkie WTF, po czym włączyłem znowu pierwszy stopień optymalizacji - zaczęło działać.
    Czyli:
    brak optymalizacji = nie działa
    -O1 = działa
    -O2 (oraz wyższe) = nie działa
    Był wieczór, więc wyłączyłem Lazarusa i darowałem sobie dokładne szukanie błędu; ostatecznie gdzieś pomiędzy kolejnymi commitami musiałem go poprawić, bo jak sobie o tym WTF-ie przypomniałem parę dni późnej, wszystko było ok.
    Wciąż jednak nie wiem, co naprawiłem, bądź co we FPC zostało zepsute ;P

  2. jeżeli zmienna jest alokowana w rejestrze, na początku funkcji wartość tego rejestru jest wrzucana na stos, a pod koniec zdejmowana.
    Czyli jeżeli jeżeli mamy np.dwie zmienne zachowane w rejestrach eb3 oraz es3, funkcja wygląda w uproszczeniu tak:

add(stp,1)
push(es3)
push(eb3)
// skompilowane ciało funkcji
pop(eb3)
pop(es3)
sub(stp,1)

Jednak wprowadzając szybkie poprawki (korzystając z dobrodziejstw pętli for..in oraz Ctrl+C Ctrl+V), omyłkowo wkleiłem taki kod pod koniec generatora:

For Symbol in SymbolList Do // each symbol
 if (Symbol.Typ = lsVariable) Then // if variable
  With Symbol.mVariable do
   if (MemPos > 0) Then // if allocated in register
    PutOpcode(o_pop, ['e'+Typ.RegPrefix+IntToStr(MemPos)]);

Przez co skompilowana funkcja wyglądała tak:

push(es3) // wrzucenie na stos `stringa`
push(eb3) // wrzucenie na stos wartości `boolean`
// ciało funkcji
pop(es3) // pobranie ze stosu wartości `string` do rejestru
pop(eb3) // pobranie ze stosu wartości `boolean` do rejestru

Jak widać, do rejestru es3 typu string pobierana zostawała wartość boolean, co skutkowało błędem maszyny wirtualnej.
Odnalezienie tego zajęło mi dwa dni, i od tego czasu już nie kopiuję bezpośrednio nawet małych kawałków kodu :P

0

Znalazłem dzisiaj w kodzie metodę z 21 parametrami wejściowymi.

        public virtual ActionResult StoreProductBrowse(int? categoryId,
                                               string searchPhrase, string searchByName, string searchByDesc,
                                               string searchByMan, string uniqueUrl, int? searchByPriceFrom,
                                               int? searchByPriceTo, bool? isOtherBranch,
                                               bool advancedSearch = false, bool searchDesc = false,
                                               bool searchByNameSel = false, bool searchByDescSel = false,
                                               bool searchByManSel = false, bool searchByPriceSel = false,
                                               WebSiteDto webSite = null, int page = 1, int numberToShow = 10,
                                               int? skipToPage = null, byte presentationType = 0, int webSiteId = 0)

Chryste Panie, jak można było to tak napisać. Jak na ten moment rekord w kodzie. Do tej pory znalazłem kilka z 14 i 15, ale to było już zbyt mocne.

0

To nie jest programistyczne, ale na pewno wielkie WTF.
Mój znajomy przesiadł się 3 lata temu na Windows 7 i chciał tam zainstalować taką swoją ulubioną grę (City Life). Okazuje się jednak, że ta gra robi dość ciekawe efekty na tym systemie - po instalacji żąda ponownego uruchomienia komputera, a gdy się to zrobi, wywala się pełno błędów, zaś system nie włącza się do końca, lecz wyświetla informacje o próbie naprawy. Okazało się, że te próby się nie udały i trzeba było przywrócić system z kopii zapasowej.
Poszperałem później w internecie i znalazłem sposób - przed ponownym uruchomieniem komputera trzeba było zainstalować jakąś łatkę. Zainstalowałem mu więc grę i wszystko działało.
Teraz zmierzam do meritum sprawy: Kolega zadzwonił do mnie przedwczoraj i powiedział, że ma mało pamięci (zgaduję, że chodzi o dysk twardy) i strasznie mu muli komputer. Zaproponowałem mu, że za kilka dni do niego przyjadę i mu sformatuję komputer. Kolega odinstalował sobie tą grę razem z łatką, a następnie zainstalował bez łatki, zrestartował komputer, znowu wywalił się błąd, przywrócił kopię zapasową i zainstalował grę z łatką. Dzisiaj do mnie zadzwonił i powiedział, że sam sobie sformatował komputer.

0

Kolejny WTF sprzed paru minut związany z FPC:
Mam taki prosty kod (również fragment z mojego kompilatora):

  Procedure Search(const Namespace: TNamespace);
  Var Symbol: TGlobalSymbol;
  Begin
   For Symbol in Namespace.SymbolList Do
    if (Symbol.Typ = gsType) and (Symbol.Name = TypeName) Then
    Begin
     Result := Symbol.mType;
     Exit;
    End;
  End;  

Jest to część funkcji służącej do szukania globalnych deklaracji typów w danej przestrzeni nazw; jak widać - kod przeszukuje listę symboli szukając typu o określonej nazwie, po czym zwraca go (tutaj Result odnosi się do procedury nadrzędnej, tak aby nie było zdziwienia, że "co - w jaki sposób procedura coś zwraca?!" :P).
Poprawnie działa to przy wyłączonych optymalizacjach oraz -O1, lecz dla testu włączam -O2, kompiluję i staram się skompilować jeden mały pliczek...
... i crash! Prosto na tym ifie (precyzyjniej: wykrzaczało się gdzieś na porównywaniu stringów).
Pierwsza myśl: pewnie nulll-pointer - sprawdzam, i nie - to nie to.
Następne kilkanaście myśli poprowadziło mnie do takiej formy kodu:

   For Symbol in Namespace.SymbolList Do
   Begin
    Writeln(Symbol.Name);
    if (Symbol.Typ = gsType) and (Symbol.Name = TypeName) Then
    Begin

I... to zadziałało - kod przestał się crashować na porównywaniu Symbol.Name = TypeName i działał poprawnie.
Wyniki: nie mam pojęcia dlaczego (nie chce mi się tego specjalnie debugować od strony assemblera), lecz Writeln spowodowało, że ten kod zaczął działać (aby było zabawniej, pisząc Writeln(Symbol.Typ); powracałem do punktu wejścia, czyli błędu).
Koniec końców problem rozwiązałem za pomocą funkcji AnsiCompareStr, lecz niemniej zaklasyfikowałbym to jako bug we FPC - może jak znajdę trochę wolnego czasu, to przyjrzę się temu bliżej :P

0

Nie do końca programistyczne.

Wczoraj w mojej skrzynce pojawiła się koperta od dostawcy Internetu. Data wysyłki na kopercie to 25 kwietnia. Inotel informuje w nim, że z dniem 1 maja, to jest dzisiaj, wyłącza jakąś tam usługę (akurat nie korzystam) e-backup i do dziś należało zgrać wszystkie dane aby nie przepadły.
Czyli generalnie gdybym z tego korzystał miałbym aż kilka godzin na zgranie danych.
Uroczo.

0

Wszytko mówiąca nazwa i opis błędu.
http://www.dba-oracle.com/t_ora_24344_success_with_compilation_error.htm

ORA-24344: Success with Compilation Error

ORA-24344 tells you there is a problem somewhere in your code.

1

Gmail spokojnie przyjmuje spoofowane maile i umieszcza je w skrzynce odbiorczej mimo że po wybraniu "Pokaż oryginał" wyraźnie widać:

Received-SPF: fail (google.com: domain of [email protected] does not designate 2a01:5e0:36:5001::20 as permitted sender) client-ip=2a01:5e0:36:5001::20;
Authentication-Results: mx.google.com;
spf=hardfail (google.com: domain of [email protected] does not designate 2a01:5e0:36:5001::20 as permitted sender) smtp.mail=[email protected]

Nie miałem problemu z wysłaniem do siebie zespoofowanego maila o identycznym wyglądzie jak informacja o wpłacie na payu.
Nigdzie nie ma najmniejszego ostrzeżenia a wiadomość dodatkowo została oznaczona jako ważna "głównie ze względu na słowa zawarte w wiadomości"

Dodam że nie jeden przedmiot do tej pory wysłałem tylko na podstawie takiego maila, bo nie chciało mi się logować do allegro żeby sprawdzić wpłatę - dzisiaj postanowiłem sprawdzić czy nie za bardzo ufam "systemowi" i okazało się że właśnie tak jest

Jak dla mnie porażka roku :O

Bonusowo - w gmail nie można niepostrzeżenie ustawić przekazywania poczty. Po włączeniu przekazywania przez tydzień pokazywana jest informacja w widocznym miejscu że poczta jest przekazywana żeby użytkownik był tego w pełni świadom.
Ale uzyskując chwilowy dostęp do konta google można za to napisać jednolinijkowy skrypt w google apps script który będzie robił dokładnie to samo i już bez żadnego ostrzeżenia, potwierdzenia ani nawet śladu w ustawieniach konta

0

Protokol UDP zawstydza poczte polska, potrafi gubic pakiety na lokalnej maszynie bez dostepu do internetu ;)
user image

0

Chciałem zoptymalizować obliczenia zmiennoprzecinkowe.
Napisałem krótki programik mierzący czas (w ms) wywołania funkcji.

int main()
{
	clock_t start = clock();
	int wynik = funkcja_która_coś_długo_liczy();
	// printf("%d\n", wynik);
	clock_t stop = clock();
	printf("wynik %d czas %ld\n", wynik, stop-start);
}

Efekt programu:
wynik 381742 czas 0
Mimo że program wykonuje się kilka sekund, czas wykonania zawsze pokazuje zero.

WTF?

Okazuje się, że kompilator zastosował coś, co wydawało mi się w C++ niedopuszczalne: leniwą ewaluację.
funkcja_która_coś_długo_liczy() wykonuje się dopiero gdy jej wynik jest potrzebny (w printf), a oba wywołania clock() wykonują się natychmiast jedno po drugim.
Żeby zmierzyć rzeczywisty czas, muszę użyć zmiennej wynik wewnątrz pomiaru, np. odkomentować linijkę z dodatkowym printf.

Mimo że widzę co się dzieje, nadal nie rozumiem jak to w C++ może być dopuszczalnym zachowaniem.
Visual 2012.

0

Win8 co chwilę gasiła mi monitor i musiałem go odblokowywać.
W opcjach zasilania miałem ustawione wszytko dobrze, i nic mi to nie dawało.
W końcu poszukałem na googlach i oto co znalazłem:

This was way trickier than I expected. You need to alter one registry value:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\7516b95f-f776-4464-8c53-06167f40cc99\8EC4B3A5-6868-48c2-BE75-4F3044BE88A7]\Attributes

Value Data = 2 (0x00000002)

After that, go back to your power settings in "Power Options" - "Advanced Power Settings". Now go to the "Display" item and a new option appears. It says "Console lock display off timeout" set this value and everything will be good.

Jakim trzeba być sadystą, lub co trzeba ćpać, żeby coś takiego wymyślić?

0

Pracuję nad aplikacją, która jest napisana w sposób tragiczny. Zaś najgorsze jest to, że dla 168 tabeli w bazie nie ma stworzonych kluczy obcych dla przynajmniej 2/3 relacji. Jest zadanie na usunięcie wszystkich danych związanych z jednym podmiotem z bazy. A, że ten podmiot ma macki praktycznie całości tabelek, to skrypt usuwający te dane ma ogromną długość. Dodatkowo nie można być pewnym, że usunięto poprawnie wszystkie dane bo bez kluczy przy takiej ilości tabeli o rozspójnienie nie trudno, a zauważymy to dopiero kiedy aplikacja padnie po jakiejś szczególnej akcji. W Dependencies danej tabeli nie widać relacji bo nie ma kluczy, trzeba każdą tabelę przechodzić i patrzeć, czy nie ma odpowiedniego identyfikatora. Ehh....

2

Dlaczego powinni zabronić używania słowa partial przez developerów?

Aplikacja webowa - kontroler. Aby uniknąć zbyt dużego jednego pliku, rozbito go na części. Teraz jeden kontroler znajduje się w 16 plikach i posiada 150 metod. Łącznie posiada prawie 6000 linii kodu.

0

Pseudokod z (unieważnionego - każdy chyba widzi dlaczego) zadania z tegorocznej matury rozszerzonej z informatyki:

http://pastebin.com/c6V8FCUc

Jak zwykle fail ze strony CKE.

1

przenosiny systemu do amazona. Powstało kilka zmian w kodzie. Czas testów wydajnościowych. Okazuje się że zapis do bazy trwa 0.5s. Przy czym obciążnie systemu to jeden user :D
Najpierw przypuszczenie żę coś nie tak na z bazą. Okazuje się żę baza wykonuje zapytanie krócej niż 10ms. Nie mieliśmy już kompletnie pomysłu o co chodzi więc zaczęliśmy logować wszystko. Okazało się że wywołanie metody trwa ~500ms natomiast ona sama wykonuje się ~10ms. Hmmm magia springa, aspektów i kto wie czego jeszcze. Oczywiście metoda była wykonana w transakcji(po wyłączeniu transakcji zaczęło działać przyzwoicie).
Okazało się że gdzieś przez pomyłkę w jednym z xml'i zmieniliśmy fragment jedenj linijki - ustawiliśmy nie ten dataSource dla transactionManagera.
W efekcie otwieraliśmy transakcje do bazy będącej w zupełnie innej sieci w zupełnie innej części świata, w której wykonywaliśmy zapytanie do bazy znajdującej się w amazonie.
Jak już gdzieś na tym forum było, "..programiści Javy nie zawsze do końća wiedzą co dokładnie robi ich kod...".

0

Może nie klasyczny WTF, ale i tak ciężko się zdziwiłem. Siedzę obecnie i produkuję widoki na potrzeby hurtowni danych. Większość z nich to zrzuty tabel 1:1, poza jednym w którym mam 4x LEFT JOIN przez pół modelu danych (z czego jeden wynika z kijowatości przyjętych zasad mapowania dziedziczenia). Zaniepokojony szybkością działania zapytania o takiej konstrukcji napuściłem na nie testy wydajności... Okazało się, że zapytanie z czterema joinami jest szybsze niż zapytanie na jedną tabelę (inty+varchar2) bez warunków (po prostu select * from X)...

2

Ostatnio w mojej firmie prowadzili rekrutacje, do zrobienia była prosta aplikacja, trafiła się perełka, programista który ponoć miał 2 lata doświadczenia napisał sobie funkcję do parsowania intów:

        public int tryParseInt(object obj)
        {
            if (obj == null)
                return 0;
            return tryParseInt(obj.ToString());
        }
0

Z serii JS jest dziwny:

++[[]][+[]]+[+[]] 

Daje 10

0

Dziś trafiłem na kawałek kodu z 2009 roku

try
{
   data = GetData();
}
catch
{
   throw;
}

Moja reakcja WTF + :D

0

W nowym wspaniałym standardzie C++11 nie będzie semaforów. Może dodadzą to w standardzie C++ 2099 gdy wszystkie inne języki będą już używały pamięci transakcyjnej ;)

Tak wiem ze semafor można zaimplementować przy pomocy conditional variables, ale skoro to takie proste czemu do uja nie dali tego w obecnym standardzie???

0

Nie w kodzie, ale programistyczne...
Miałem wysłać znajomym foty z imprezy. Kilkanaście plików PNG po ~8-11MB każdy.

 gzip -c img*.png > foty.zip

Spakowało tylko jeden 8MB plik... wynikowy zip miał 344MB...

0

Ale kilka skonkatenowanych plików .gz archiwum .zip nie czyni...

0

4 błędy i 11 warnów:

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<pair<double, double>> tab;
	return(0);
}

To już chula...

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector< pair<double, double> > tab;
	return(0);
}
0

Z kalkulatora pożyczek na stronie alior sync: http://pozyczka.sync.pl/bfo/

var json = "[\
  [1000,90.50,48.73,34.91,28.09,24.06,21.42,19.58,18.24,17.23,16.44],\
  [2000,181.00,97.45,69.83,56.18,48.11,42.84,39.16,36.48,34.45,32.89],\
  [3000,271.50,146.18,104.74,84.26,72.17,64.26,58.74,54.71,51.68,49.33],\
  [4000,362.01,194.91,139.65,112.35,96.22,85.68,78.32,72.95,68.90,65.77],\
  [5000,452.51,243.63,174.56,140.44,120.28,107.10,97.90,91.19,86.13,82.21],\
  [6000,543.01,292.36,209.48,168.53,144.33,128.52,117.48,109.43,103.35,98.66],\
  [7000,633.51,341.09,244.39,196.61,168.39,149.94,137.06,127.66,120.58,115.10],\
  [8000,724.01,389.81,279.30,224.70,192.45,171.36,156.64,145.90,137.80,131.54],\
  [9000,814.51,438.54,314.21,252.79,216.50,192.78,176.22,164.14,155.03,147.98],\
  [10000,905.02,487.27,349.13,280.88,240.56,214.20,195.80,182.38,172.25,164.43],\
  [15000,1357.52,730.93,523.69,421.32,360.83,321.30,293.71,273.57,258.38,246.64],\
  [20000,1810.03,974.54,698.25,561.75,481.11,428.40,391.61,364.76,344.51,328.86],\
  [25000,2262.54,1288.17,872.81,702.19,601.39,535.49,489.51,455.95,430.63,411.07],\
  [30000,2715.05,1461.80,1047.38,842.63,721.67,642.59,587.41,547.13,516.76,493.28],\
  [35000,3167.55,1705.44,1221.94,983.07,841.95,749.69,685.31,638.32,602.89,575.50],\
  [40000,3620.06,1949.07,1396.50,1123.51,962.23,856.79,783.21,729.51,689.01,657.71],\
  [45000,4072.57,2192.70,1571.07,1263.95,1082.50,963.89,881.12,820.70,775.14,739.92],\
  [50000,4525.08,2436.34,1745.63,1404.39,1202.78,1070.99,979.02,911.89,861.27,822.14],\
  [60000,5430.09,2923.61,2094.75,1685.26,1443.34,1285.19,1174.82,1094.27,1033.52,986.57],\
  [70000,6335.11,3410.87,2443.88,1966.14,1683.90,1499.38,1370.62,1276.65,1205.77,1150.99],\
  [80000,7240.12,3898.14,2793.01,2247.02,1924.45,1713.58,1566.43,1459.03,1378.02,1315.42],\
  [90000,8145.14,4385.41,3142.13,2527.90,2165.01,1927.78,1762.23,1641.40,1550.28,1479.85],\
  [100000,9050.15,4872.68,3491.26,2808.77,2405.56,2141.98,1958.04,1823.78,1722.53,1644.28]\
]"; 

// ...
    jsonObj = jQuery.parseJSON( json );

ekhm... :|
widzę, że jQuery jest już niezbędny nawet do utworzenia prostej tablicy ;)

dla niewtajemniczonych - JSON to format wymiany danych w formacie zgodnym z javascript - wystarczyło usunąć cudzysłowy żeby uzyskać tablicę. Autor natomiast z tablicy w javascript stworzył stringa w javascript (do którego musiał jeszcze dodać backslashe żeby go rozbić na parę linii), którego następnie parsuje dość dużą biblioteką, żeby z powrotem uzyskać tablicę :O
(autor nie zna też najwyraźniej znaczenia słówka var i cały globalny obiekt window jest zasyfiony zmiennymi, które miały być lokalne)

0

Dostaje zgłoszenie, ze rabaty dla przy zakończeniu zamówienia w sklepie naliczają się podwójnie. Wchodzę i widzę jeden wielki WTF, kod spaghetti wielkości FSM. Ale najtragiczniejsze, ze dla pobranie ceny dla np. 10 towarów wywoła sie 30 procedur składowanych wyliczajacych cenę dla pojedynczego towaru (cena towaru + różnego rodzaju promocje). Ktoś napisał pętlę iterujaca po id produktów i wywołują bardzo złożone zapytanie. Dodatkowo użyto ja 3 razy bo kolejne osoby nie ogarnęły ze juz wyliczono cenę i robią to kolejny raz. Najgorsze ze składanie zamówień jest kluczowe w aplikacji i takie coś tragicznie spowolni prace aplikacji i zwiększy drastycznie obciążenie Azure. A zrefaktoryzowac nie wolno bo puszczamy aplikacje a to by opóźniło wyjście o jakiś tydzień lub więcej z testami wszystkich mechanizmów. Kuzwa, jak mi się nie chce przy tym pracować...

0

@unikalna_nazwa coś podobnego mam

Na zapytania Ajaxowe kontroler może zwrócić JsonResult, który ma pole Data będące typu object. Ktoś od nas wymyślił, że stworzy wrapper:

    public class JSONModel
    {
        public bool Success { get; set; }

        public string Text { get; set; }
    }

i go będzie wrzucał do Data, tak by stworzyć podwaliny pod standard odbierania wiadomości w widokach, czy udała się akcja czy nie i do tego jakiś komunikat.
Tylko teraz jak przesłać obiekt jak się udało? Można stworzyć klasę dziedziczącą po JSONModel. Albo dodać nowe pole Data, co wygląda brzydko, ale jest proste i łatwe.
Ale po co sobie życie upraszczać? Można zostawić tak jak jest i do Text wrzucać obiekty po serializacji do JSON, a w widoku go deserializować. Albo kolejne wartości wrzucać po średnikach i w widoku sobie split zrobić. Błędogenność i bezsensowne parsowanie uber alles. JSON in JSON.
user image

0

To jest zarówno WTF jak i gorzkie żale dotyczące POSRANYCH (tak, posranych) bugów jakie istnieją w Webkicie (Chrome). Od lat gdy piszę coś fajnego, testując głównie na Operze (jeszcze Presto), która dość "mocno" trzyma się standardów i najmniej pozwala na wybryki - wszystko działa fajnie, jakiś czas były poprawki ekstra dla IE6/7, zwykle działało wszędzie, a w Chrome jakiś debilny bug. Te bugi nie raz wisiały w trackerze po 2-3 lata zanim zostały poprawione, zwykle dało się to jakoś obejść, ale było ostro wkurzające. Na aktualny problem jeszcze nie znam rozwiązania.

Otóż mam jakąś tam stronkę, w niej pokazuję warstwę wierzchnią jako "preloader" - strona cała jest ładowana na raz, potem dynamicznie się wszystko przesuwa itd itd. Warstwa wierzchnia to <div id="site_loader"></div>
Fragment css:

.slogan {
    background: rgba(0,0,0,.6); /* linia 351 */
}
#site_loader {
    background: rgba(255,255,255,0.97) url("./images/-1.gif") center center no-repeat; /* linia 625 */
}

Czyli - mój preloader powinien mieć białe tło i gifa na nim. Wszystko fajnie, i tak właśnie to sobie działało (nawet na webkicie). Stronę przerzuciłem na produkcję, dziś odpalam sobie ją na Operze Next (Webkit) - a tam pół-czarne tło i loader. Pierwsza myśl - tło się załaduje później. Potem - przecież to nie był obrazek, a kolor..

Najpierw pomyślałem - błąd nowej Opery. Patrzę pod Chrome - to samo :/ Inspekcja elementu wykazuje, że mój element w 1251 linii ma nadany styl background: rgba(0,0,0,0.6) url("./images/-1.gif") center center no-repeat;, se myślę - wtf? Przechodzę do pliku css - niestety, kończy się on na 700 liniach :/ Potem widzę, że Chrome widzi ten plik z podwójnymi znakami nowej linii (wtf, nie ogarnia CRLF?) i stąd to rozejście. Dzielę to przez dwa i trafiam na deklarację z białym tłem. Myślę - skąd to czarne tło z alphą 0.6 - wyszukuję w pliku css - tylko element .slogan ma takie tło. Z cholera wie jakiego powodu Webkit łączy te dwie reguły (wszak robi się czarne tło, ale zostaje gif i jego ułożenie) i to z elementów o niepasujących selektorach. W dodatku nawet gdyby mój element miał klasę slogan to przecież selektor wg klasy jest mniej ważny niż selektor po id, więc tak czy siak tło powinno być białe.

Nawet nie wiem jak zabrać się za debugowanie tego. Ot Webkit zdecydował sobie do elementu przypisać kawałek innego stylu z losowego miejsca w pliku o.O

PS. Plik css jest poprawny, nie ma nic niepodomykane i nie ma żadnych innych problemów z nim.

PS2. Nie chce mi się tego zgłaszać. Stronę jeszcze będę rozbudowywał i zmieniał - jeżeli po całkowitym ukończeniu tak to zostanie to zgłoszę i podam linka do strony, bo nie wiem jak to zreprodukować - obie reguły istniały wcześniej i było ok, po bliżej nieokreślonych zmianach się zepsuło.

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