Tweets by @buherablog
profile for buherator at IT Security Stack Exchange, Q&A for IT security professionals

A BitBetyár Blog

Túljártál a nagyokosok eszén? Küldd be a mutatványodat! (e-mail a buherator gmailkomra jöhet)

Full-Disclosure / Névjegy / Coming out


Promó

H.A.C.K.

Címkék

0day (110) adobe (87) adobe reader (21) anonymous (26) apple (60) az olvasó ír (49) blackhat (20) botnet (22) bug (200) buherablog (44) buhera sörözés (39) bukta (49) deface (38) dns (22) dos (29) esemény (82) facebook (26) firefox (64) flash (33) gondolat (31) google (59) google chrome (36) hacktivity (37) hírek (117) incidens (224) internet explorer (88) iphone (35) java (50) jog (22) kína (21) kriptográfia (68) kultúra (21) linux (24) malware (43) microsoft (142) móka (48) mozilla (23) office (26) oracle (40) os x (43) patch (197) php (20) politika (31) privacy (58) programozás (22) safari (34) sql injection (62) windows (85) xss (77) Címkefelhő

Licensz

Creative Commons Licenc

Zune - MitÍrKi?

2009.01.03. 13:05 | buherator | 32 komment

A programozás ZH-k szerelmeseinek íme a kódrészlet, ami (állítólag) a Zune dátum paráját okozta:

BOOL ConvertDays(UINT32 days, SYSTEMTIME* lpTime)
{
    int dayofweek, month, year;
    UINT8 *month_tab;

    //Calculate current day of the week
    dayofweek = GetDayOfWeek(days);

    year = ORIGINYEAR;

    while (days > 365)
    {
        if (IsLeapYear(year))
        {
            if (days > 366)
            {
                days -= 366;
                year += 1;
            }
        }
        else
        {
            days -= 365;
            year += 1;
        }
    }


    // Determine whether it is a leap year
    month_tab = (UINT8 *)((IsLeapYear(year))? monthtable_leap : monthtable);

    for (month=0; month<12; month++)
    {
        if (days <= month_tab[month])
            break;
        days -= month_tab[month];
    }

    month += 1;

    lpTime->wDay = days;
    lpTime->wDayOfWeek = dayofweek;
    lpTime->wMonth = month;
    lpTime->wYear = year;

    return TRUE;
}

A kérdés magától értetődik: hol a hiba?

Címkék: zune programozás

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

sghctoma · http://sghctoma.extra.hu 2009.01.03. 13:53:42

jujj, de szééép... nasty little csak-néha-végtelen ciklus :D

Bit Rot 2009.01.03. 21:25:28

Ekkora gányolást!

Mi a lósz*r ez???

Ha jól látom: input: napok (ORIGINYEAR január 1 óta)
Output: struktúra day, dayofweek, month, year-el kitöltve.

De ki volt ezt képes újra megírni (pláne így), amikor erre van millió library függvény?

Bit Rot 2009.01.03. 21:26:28

@bodzasfanta:
Mármint az "if (days > 366)"-nak a nem létező else ágára gondoltál, ugye? (ami a days = 366-ot kezelné.)

sghctoma · http://sghctoma.extra.hu 2009.01.03. 22:17:49

@John42: igen én sem teljesen értettem, hogy miért nem volt jó nekik egy GetSystemTime hívás.. WinCE-ben implementálva van, és a Zune oprendszere CE alapú, ha jól tudom...

gadget 2009.01.03. 23:48:55

a hibas kod egy Freescale chip drivereben talalhato, igy a bug nem Zune specifikus...pl Toshiba Gigabeat S szeria szinten megdoglott abban a boldog oraban :)

szádba szarok 2009.01.04. 13:59:43

akkurvannyát, ezt melyik barom írta?! így kell:

while (days > (d = IsLeapYear(year) ? 366 : 365)) {
++year;
days -= d;
}

rövidebb, egyszerűbb, olvashatóbb, van jelentése a feltételnek, és mellesleg működik.

synapse · http://www.synsecblog.com 2009.01.04. 14:09:52

@szadba...: inicializaciot vegyuk ki azert a ciklus ele ;)

"Zune"-os kodban azert vicces a fuckup

1: while (days > 365)
2: if (days > 366) :))))

synapse

P1ngW1n 2009.01.04. 14:31:16

pastie.org/349916

// Global Variables
//These macro define some default information of RTC
#define ORIGINYEAR 1980 // the begin year
#define MAXYEAR (ORIGINYEAR + 100) // the maxium year
#define JAN1WEEK 2 // Jan 1 1980 is a Tuesday
#define GetDayOfWeek(X) (((X-1)+JAN1WEEK)%7)


Lesz itt még baj 2080-ban is :DDD

szádba szarok 2009.01.04. 15:13:52

@synapse: szeirntem félreérted ezt a bonyolult kódot.. milyen inicializációt és minek? gondold végig, mert megalázlak.

synapse · http://www.synsecblog.com 2009.01.04. 15:41:27

d = IsLeapYear(year) ? 366 : 365); d) {
++year;
days -= d;
}

Alazol? Ajajjj :D

synapse

synapse · http://www.synsecblog.com 2009.01.04. 15:42:13

d = IsLeapYear(year) ? 366 : 365);
while (days > d) {
++year;
days -= d;
}

Na, igy. Kurva tacspad :D

synapse

EQ · http://rycon.hu 2009.01.04. 16:34:33

ciklus előtt inicializáció mánia by synapse :) de jogos :)

synapse · http://www.synsecblog.com 2009.01.04. 16:41:25

Hat ugyanazt kiertekelni minden iteracioban nem igazan ertelmes. De azert erzem, hogy ezert meg nagyon, NAGYON meg leszek alazva :D:D:D:D:D

Amugy a multkori meglett EQ?

synapse

Udi · http://blog.udi.hu 2009.01.04. 16:54:53

Synapse drága...
A year minden egyes cikluslépésben növekszik. Befejezzem a gondolatot?

PS: 1980 szökőév.

EQ · http://rycon.hu 2009.01.04. 17:33:10

nem segfaultol és 3oprendeszeren 4gépen, 12processként fut mint teszt, szóval működik egyenlőre :)

szádba szarok 2009.01.04. 17:39:06

@synapse: na mert bezzeg faszságot írni kommentbe, na az meg pláne igazán értelmes.
mert ha szólok, hogy faszságot írtál (mint ahogy tényleg), akkor ahelyett hogy elgondolkodnál, hogy talán valóban fasz vagy, nagyarccal visszaszólsz, és mondod tovább a magad baromságát. na ez NAGYON gáz.
minthogy annyira ostoba vagy, hogy egy három értékadásból egy egy összehasonlításból álló kódot nem bírsz felfogni, hát megszánlak, és elmagyarázom.
a ciklus invariánsa, hogy a keresett nap a year év jan.1-étől számolva, a day-edik nap. ez minden interáció előtt és után teljesül. mivel a ciklusfeltételben a d mindig pontosan azt az értékes kapja, ahány napja a year évnek van, a ciklusfeltétel azt jelenti, hogy "a keresett nap nem a year évben van". ha ez teljesül, akkor ugrik a következő évre. ezt jelenti a "++year;" a year tehát minden kurva iterációnál változik. (gondolom még soha nem találkoztál a ++ operátorral, és ez okozta a problémát.) hogy az invariánst megtartsa, ezután a napok számát éppen annyival csökkeni, ahány nap az adott évben van. azaz d-vel. miven a days minden interációban szigorúan csökken, a ciklus garantáltan véget ér.
tehát a kódom helyes.
te meg hülye vagy.
és túl nagy az arcod.

synapse · http://www.synsecblog.com 2009.01.04. 17:43:52

"A year minden egyes cikluslépésben növekszik. Befejezzem a gondolatot?"

Ahaha, hat ezt bizony kurvara beneztem, igazad van. :)

synapse

synapse · http://www.synsecblog.com 2009.01.04. 17:47:13

@szádba szarok

ja, beneztem, kurvaokos vagy gratulalok. Viszont a stilusod miatt kijarna neked egy alapos szajbaveres.

synapse

Udi · http://blog.udi.hu 2009.01.04. 18:13:49

@Szádba szarok

A kérdéses évben (ami végtelenre viszi az eredetit), a tied hibás eredményt hoz.

Jó lenne tudni, hogy a days paraméterrel történik e valami érdekes, mielőtt megkapja a fv.

szádba szarok 2009.01.04. 18:41:12

@Udi: az eredeti a szökőévet követő évek jan1-eitől száll áll. pontosan milyen paraméterre ad hibás eredményt az enyém? mit kéne, és mit ad?

gadget 2009.01.04. 19:04:31

@szadba szarok:
a szokoevek utolso napjan szall el az eredeti kod, de ettol fuggetlenul szvsz rendben van a cilklus amit irtal...

talan ez meg olvashatobb es egyszerubb:
while (days > 365 + IsLeapYear(year)) {
days -= 365 + IsLeapYear(year);
year++;
}

gadget 2009.01.04. 19:11:21

hogy csak egyszer kelljen IsLeapYear-t hivni:

while (days > (d = 365 + IsLeapYear(year))) {
days -= d;
year++;
}

szádba szarok 2009.01.04. 19:16:23

@gadget: igaz, dec31.. (most nézem, 1-től kezdi a számozást..) amúgy a fene tudja, hogy a bool true az int-ként mennyit ért... lehet hogy az IsLeapYear() 59-et ad vissza szökőévre.. kurvára nem lepődnék meg azon se, ha így lenne :D

gadget 2009.01.04. 19:30:53

@szádba szarok:
bool int-re castolva mindig 0/1

utananeztem az IsLeapYear fv. implementaciojanak (egy ujabb csodakod)...bool helyett direktbe int-et ad vissza (0/1), szal vegul is mukodhet a fenti ciklusom

bit-player.org/2009/the-zune-bug

szádba szarok 2009.01.04. 19:36:16

@gadget:
"bool int-re castolva mindig 0/1"
hogyne, c++-ban. meg 200 másik nyelven is. c-ben pont nem. ott nincs is beépített bool típus.

gadget 2009.01.04. 20:01:40

@szádba szarok:
tenyleg, errol el is feledkeztem...de mivel int 0/1-et ad vissza, a kodomnak mukodnie kell

ha a hivatalos fixet ugyanaz a zseni koveti el aki az eredeti kodot, akkor ugyis csak else agon egy break; lesz a javitas :)

sghctoma · http://sghctoma.extra.hu 2009.01.04. 21:54:33

egy apró megjegyzés a bool dologgal kapcsolatban: ha jól látom, a kódban sehol sincs bool, mindenhol BOOL van, ami meg int..

Udi · http://blog.udi.hu 2009.01.05. 12:37:46

@szádba szarok:

Én javában teszteltem, és így inicializáltam az inputot:
private static final Calendar epoch = new GregorianCalendar(1980,1,1,0,0);
private static final GregorianCalendar d = new GregorianCalendar(2008,12,31,0,0);

aztán
days = Math.round((float)(teszt.d.getTimeInMillis()-teszt.epoch.getTimeInMillis())/1000/60/60/24);

Nem szép, tudom. Valami nem volt kerek, mert 2009.1.1 inputtal futott végtelen ciklusra. Miután kilőttem a hibát tesztelni kezdtem a többi algoritmust is. Az eredeti 0-t ad, a tied pedig nem lép be az utolsó iterációba, és 365 lesz a végeredmény.
Egyik se helyes megoldás.

Ha a days-hez hozzáadsz egyet inikor, akkor is más eredmények jönnek ki.

Fura probléma, és nincs is kedvem már többet foglalkozni vele. Annyit sejtek, hogy a probléma magja, az hogy 1980.1.1 az általuk használt epoch.

Én ezt írtam:
while (days >365){
days -= 365;
if(d.isLeapYear(year)&&days>1)days--;
year++;
}
PS: teljesség kedvéért, a te algoritmusod javában:
int day = 0;
while (days > (day = d.isLeapYear(year) ? 366 : 365)) {
year++;
days -= day;
}

Udi · http://blog.udi.hu 2009.01.05. 12:43:10

@gadget:

while (days > (d = 365 + (IsLeapYear(year)!=0?1:0))) {
days -= d;
year++;
}

és mindenki boldog :D

szádba szarok 2009.01.05. 14:32:28

@Udi:
ays = Math.round((float)(teszt.d.getTimeInMillis()-teszt.epoch.getTimeInMillis())/1000/60/60/24);
ez 0-tól sorszámozza a napookat, az eredeti meg 1-től.

keeroy · http://music.blog.hu 2009.01.07. 01:49:56

Poppe tanár úr igen büszke lenne! :)