test_util.c 152 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2015, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #define COMPAT_PRIVATE
  7. #define CONTROL_PRIVATE
  8. #define MEMPOOL_PRIVATE
  9. #define UTIL_PRIVATE
  10. #include "or.h"
  11. #include "config.h"
  12. #include "control.h"
  13. #include "test.h"
  14. #ifdef ENABLE_MEMPOOLS
  15. #include "mempool.h"
  16. #endif /* ENABLE_MEMPOOLS */
  17. #include "memarea.h"
  18. #include "util_process.h"
  19. #ifdef _WIN32
  20. #include <tchar.h>
  21. #endif
  22. #include <math.h>
  23. #include <ctype.h>
  24. /* XXXX this is a minimal wrapper to make the unit tests compile with the
  25. * changed tor_timegm interface. */
  26. static time_t
  27. tor_timegm_wrapper(const struct tm *tm)
  28. {
  29. time_t t;
  30. if (tor_timegm(tm, &t) < 0)
  31. return -1;
  32. return t;
  33. }
  34. #define tor_timegm tor_timegm_wrapper
  35. static void
  36. test_util_read_until_eof_impl(const char *fname, size_t file_len,
  37. size_t read_limit)
  38. {
  39. char *fifo_name = NULL;
  40. char *test_str = NULL;
  41. char *str = NULL;
  42. size_t sz = 9999999;
  43. int fd = -1;
  44. int r;
  45. fifo_name = tor_strdup(get_fname(fname));
  46. test_str = tor_malloc(file_len);
  47. crypto_rand(test_str, file_len);
  48. r = write_bytes_to_file(fifo_name, test_str, file_len, 1);
  49. tt_int_op(r, OP_EQ, 0);
  50. fd = open(fifo_name, O_RDONLY|O_BINARY);
  51. tt_int_op(fd, OP_GE, 0);
  52. str = read_file_to_str_until_eof(fd, read_limit, &sz);
  53. tt_assert(str != NULL);
  54. if (read_limit < file_len)
  55. tt_int_op(sz, OP_EQ, read_limit);
  56. else
  57. tt_int_op(sz, OP_EQ, file_len);
  58. tt_mem_op(test_str, OP_EQ, str, sz);
  59. tt_int_op(str[sz], OP_EQ, '\0');
  60. done:
  61. unlink(fifo_name);
  62. tor_free(fifo_name);
  63. tor_free(test_str);
  64. tor_free(str);
  65. if (fd >= 0)
  66. close(fd);
  67. }
  68. static void
  69. test_util_read_file_eof_tiny_limit(void *arg)
  70. {
  71. (void)arg;
  72. // purposely set limit shorter than what we wrote to the FIFO to
  73. // test the maximum, and that it puts the NUL in the right spot
  74. test_util_read_until_eof_impl("tor_test_fifo_tiny", 5, 4);
  75. }
  76. static void
  77. test_util_read_file_eof_one_loop_a(void *arg)
  78. {
  79. (void)arg;
  80. test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
  81. }
  82. static void
  83. test_util_read_file_eof_one_loop_b(void *arg)
  84. {
  85. (void)arg;
  86. test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
  87. }
  88. static void
  89. test_util_read_file_eof_two_loops(void *arg)
  90. {
  91. (void)arg;
  92. // write more than 1024 bytes to the FIFO to test two passes through
  93. // the loop in the method; if the re-alloc size is changed this
  94. // should be updated as well.
  95. test_util_read_until_eof_impl("tor_test_fifo_2k", 2048, 10000);
  96. }
  97. static void
  98. test_util_read_file_eof_two_loops_b(void *arg)
  99. {
  100. (void)arg;
  101. test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
  102. }
  103. static void
  104. test_util_read_file_eof_zero_bytes(void *arg)
  105. {
  106. (void)arg;
  107. // zero-byte fifo
  108. test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000);
  109. }
  110. /* Test the basic expected behaviour for write_chunks_to_file.
  111. * NOTE: This will need to be updated if we ever change the tempfile location
  112. * or extension */
  113. static void
  114. test_util_write_chunks_to_file(void *arg)
  115. {
  116. char *fname = NULL;
  117. char *tempname = NULL;
  118. char *str = NULL;
  119. int r;
  120. struct stat st;
  121. /* These should be two different sizes to ensure the data is different
  122. * between the data file and the temp file's 'known string' */
  123. int temp_str_len = 1024;
  124. int data_str_len = 512;
  125. char *data_str = tor_malloc(data_str_len);
  126. char *temp_str = tor_malloc(temp_str_len);
  127. smartlist_t *chunks = smartlist_new();
  128. sized_chunk_t c = {data_str, data_str_len/2};
  129. sized_chunk_t c2 = {data_str + data_str_len/2, data_str_len/2};
  130. (void)arg;
  131. crypto_rand(temp_str, temp_str_len);
  132. crypto_rand(data_str, data_str_len);
  133. // Ensure it can write multiple chunks
  134. smartlist_add(chunks, &c);
  135. smartlist_add(chunks, &c2);
  136. /*
  137. * Check if it writes using a tempfile
  138. */
  139. fname = tor_strdup(get_fname("write_chunks_with_tempfile"));
  140. tor_asprintf(&tempname, "%s.tmp", fname);
  141. // write a known string to a file where the tempfile will be
  142. r = write_bytes_to_file(tempname, temp_str, temp_str_len, 1);
  143. tt_int_op(r, OP_EQ, 0);
  144. // call write_chunks_to_file
  145. r = write_chunks_to_file(fname, chunks, 1, 0);
  146. tt_int_op(r, OP_EQ, 0);
  147. // assert the file has been written (expected size)
  148. str = read_file_to_str(fname, RFTS_BIN, &st);
  149. tt_assert(str != NULL);
  150. tt_u64_op((uint64_t)st.st_size, OP_EQ, data_str_len);
  151. tt_mem_op(data_str, OP_EQ, str, data_str_len);
  152. tor_free(str);
  153. // assert that the tempfile is removed (should not leave artifacts)
  154. str = read_file_to_str(tempname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
  155. tt_assert(str == NULL);
  156. // Remove old testfile for second test
  157. r = unlink(fname);
  158. tt_int_op(r, OP_EQ, 0);
  159. tor_free(fname);
  160. tor_free(tempname);
  161. /*
  162. * Check if it skips using a tempfile with flags
  163. */
  164. fname = tor_strdup(get_fname("write_chunks_with_no_tempfile"));
  165. tor_asprintf(&tempname, "%s.tmp", fname);
  166. // write a known string to a file where the tempfile will be
  167. r = write_bytes_to_file(tempname, temp_str, temp_str_len, 1);
  168. tt_int_op(r, OP_EQ, 0);
  169. // call write_chunks_to_file with no_tempfile = true
  170. r = write_chunks_to_file(fname, chunks, 1, 1);
  171. tt_int_op(r, OP_EQ, 0);
  172. // assert the file has been written (expected size)
  173. str = read_file_to_str(fname, RFTS_BIN, &st);
  174. tt_assert(str != NULL);
  175. tt_u64_op((uint64_t)st.st_size, OP_EQ, data_str_len);
  176. tt_mem_op(data_str, OP_EQ, str, data_str_len);
  177. tor_free(str);
  178. // assert the tempfile still contains the known string
  179. str = read_file_to_str(tempname, RFTS_BIN, &st);
  180. tt_assert(str != NULL);
  181. tt_u64_op((uint64_t)st.st_size, OP_EQ, temp_str_len);
  182. tt_mem_op(temp_str, OP_EQ, str, temp_str_len);
  183. done:
  184. unlink(fname);
  185. unlink(tempname);
  186. smartlist_free(chunks);
  187. tor_free(fname);
  188. tor_free(tempname);
  189. tor_free(str);
  190. tor_free(data_str);
  191. tor_free(temp_str);
  192. }
  193. #define _TFE(a, b, f) tt_int_op((a).f, OP_EQ, (b).f)
  194. /** test the minimum set of struct tm fields needed for a unique epoch value
  195. * this is also the set we use to test tor_timegm */
  196. #define TM_EQUAL(a, b) \
  197. TT_STMT_BEGIN \
  198. _TFE(a, b, tm_year); \
  199. _TFE(a, b, tm_mon ); \
  200. _TFE(a, b, tm_mday); \
  201. _TFE(a, b, tm_hour); \
  202. _TFE(a, b, tm_min ); \
  203. _TFE(a, b, tm_sec ); \
  204. TT_STMT_END
  205. static void
  206. test_util_time(void *arg)
  207. {
  208. struct timeval start, end;
  209. struct tm a_time, b_time;
  210. char timestr[128];
  211. time_t t_res;
  212. int i;
  213. struct timeval tv;
  214. /* Test tv_udiff */
  215. (void)arg;
  216. start.tv_sec = 5;
  217. start.tv_usec = 5000;
  218. end.tv_sec = 5;
  219. end.tv_usec = 5000;
  220. tt_int_op(0L,OP_EQ, tv_udiff(&start, &end));
  221. end.tv_usec = 7000;
  222. tt_int_op(2000L,OP_EQ, tv_udiff(&start, &end));
  223. end.tv_sec = 6;
  224. tt_int_op(1002000L,OP_EQ, tv_udiff(&start, &end));
  225. end.tv_usec = 0;
  226. tt_int_op(995000L,OP_EQ, tv_udiff(&start, &end));
  227. end.tv_sec = 4;
  228. tt_int_op(-1005000L,OP_EQ, tv_udiff(&start, &end));
  229. /* Test tor_timegm & tor_gmtime_r */
  230. /* The test values here are confirmed to be correct on a platform
  231. * with a working timegm & gmtime_r. */
  232. /* Start with known-zero a_time and b_time.
  233. * This avoids passing uninitialised values to TM_EQUAL in a_time.
  234. * Zeroing may not be needed for b_time, as long as tor_gmtime_r
  235. * never reads the existing values in the structure.
  236. * But we really don't want intermittently failing tests. */
  237. memset(&a_time, 0, sizeof(struct tm));
  238. memset(&b_time, 0, sizeof(struct tm));
  239. a_time.tm_year = 2003-1900;
  240. a_time.tm_mon = 7;
  241. a_time.tm_mday = 30;
  242. a_time.tm_hour = 6;
  243. a_time.tm_min = 14;
  244. a_time.tm_sec = 55;
  245. t_res = 1062224095UL;
  246. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  247. tor_gmtime_r(&t_res, &b_time);
  248. TM_EQUAL(a_time, b_time);
  249. a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
  250. t_res = 1093846495UL;
  251. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  252. tor_gmtime_r(&t_res, &b_time);
  253. TM_EQUAL(a_time, b_time);
  254. a_time.tm_mon = 1; /* Try a leap year, in feb. */
  255. a_time.tm_mday = 10;
  256. t_res = 1076393695UL;
  257. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  258. tor_gmtime_r(&t_res, &b_time);
  259. TM_EQUAL(a_time, b_time);
  260. a_time.tm_mon = 0;
  261. t_res = 1073715295UL;
  262. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  263. tor_gmtime_r(&t_res, &b_time);
  264. TM_EQUAL(a_time, b_time);
  265. /* Test tor_timegm out of range */
  266. /* year */
  267. /* Wrong year < 1970 */
  268. a_time.tm_year = 1969-1900;
  269. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  270. a_time.tm_year = -1-1900;
  271. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  272. #if SIZEOF_INT == 4 || SIZEOF_INT == 8
  273. a_time.tm_year = -1*(1 << 16);
  274. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  275. /* one of the smallest tm_year values my 64 bit system supports:
  276. * t_res = -9223372036854775LL without clamping */
  277. a_time.tm_year = -292275055-1900;
  278. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  279. a_time.tm_year = INT32_MIN;
  280. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  281. #endif
  282. #if SIZEOF_INT == 8
  283. a_time.tm_year = -1*(1 << 48);
  284. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  285. /* while unlikely, the system's gmtime(_r) could return
  286. * a "correct" retrospective gregorian negative year value,
  287. * which I'm pretty sure is:
  288. * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
  289. * 730485 is the number of days in two millenia, including leap days */
  290. a_time.tm_year = -292277022657-1900;
  291. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  292. a_time.tm_year = INT64_MIN;
  293. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  294. #endif
  295. /* Wrong year >= INT32_MAX - 1900 */
  296. #if SIZEOF_INT == 4 || SIZEOF_INT == 8
  297. a_time.tm_year = INT32_MAX-1900;
  298. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  299. a_time.tm_year = INT32_MAX;
  300. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  301. #endif
  302. #if SIZEOF_INT == 8
  303. /* one of the largest tm_year values my 64 bit system supports */
  304. a_time.tm_year = 292278994-1900;
  305. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  306. /* while unlikely, the system's gmtime(_r) could return
  307. * a "correct" proleptic gregorian year value,
  308. * which I'm pretty sure is:
  309. * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
  310. * 730485 is the number of days in two millenia, including leap days */
  311. a_time.tm_year = 292277026596-1900;
  312. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  313. a_time.tm_year = INT64_MAX-1900;
  314. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  315. a_time.tm_year = INT64_MAX;
  316. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  317. #endif
  318. /* month */
  319. a_time.tm_year = 2007-1900; /* restore valid year */
  320. a_time.tm_mon = 12; /* Wrong month, it's 0-based */
  321. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  322. a_time.tm_mon = -1; /* Wrong month */
  323. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  324. /* day */
  325. a_time.tm_mon = 6; /* Try July */
  326. a_time.tm_mday = 32; /* Wrong day */
  327. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  328. a_time.tm_mon = 5; /* Try June */
  329. a_time.tm_mday = 31; /* Wrong day */
  330. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  331. a_time.tm_year = 2008-1900; /* Try a leap year */
  332. a_time.tm_mon = 1; /* in feb. */
  333. a_time.tm_mday = 30; /* Wrong day */
  334. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  335. a_time.tm_year = 2011-1900; /* Try a non-leap year */
  336. a_time.tm_mon = 1; /* in feb. */
  337. a_time.tm_mday = 29; /* Wrong day */
  338. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  339. a_time.tm_mday = 0; /* Wrong day, it's 1-based (to be different) */
  340. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  341. /* hour */
  342. a_time.tm_mday = 3; /* restore valid month day */
  343. a_time.tm_hour = 24; /* Wrong hour, it's 0-based */
  344. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  345. a_time.tm_hour = -1; /* Wrong hour */
  346. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  347. /* minute */
  348. a_time.tm_hour = 22; /* restore valid hour */
  349. a_time.tm_min = 60; /* Wrong minute, it's 0-based */
  350. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  351. a_time.tm_min = -1; /* Wrong minute */
  352. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  353. /* second */
  354. a_time.tm_min = 37; /* restore valid minute */
  355. a_time.tm_sec = 61; /* Wrong second: 0-based with leap seconds */
  356. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  357. a_time.tm_sec = -1; /* Wrong second */
  358. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  359. /* Test tor_gmtime_r out of range */
  360. /* time_t < 0 yields a year clamped to 1 or 1970,
  361. * depending on whether the implementation of the system gmtime(_r)
  362. * sets struct tm (1) or not (1970) */
  363. t_res = -1;
  364. tor_gmtime_r(&t_res, &b_time);
  365. tt_assert(b_time.tm_year == (1970-1900) ||
  366. b_time.tm_year == (1969-1900));
  367. if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
  368. t_res = -1*(1 << 30);
  369. tor_gmtime_r(&t_res, &b_time);
  370. tt_assert(b_time.tm_year == (1970-1900) ||
  371. b_time.tm_year == (1935-1900));
  372. t_res = INT32_MIN;
  373. tor_gmtime_r(&t_res, &b_time);
  374. tt_assert(b_time.tm_year == (1970-1900) ||
  375. b_time.tm_year == (1901-1900));
  376. }
  377. #if SIZEOF_TIME_T == 8
  378. {
  379. /* one of the smallest tm_year values my 64 bit system supports:
  380. * b_time.tm_year == (-292275055LL-1900LL) without clamping */
  381. t_res = -9223372036854775LL;
  382. tor_gmtime_r(&t_res, &b_time);
  383. tt_assert(b_time.tm_year == (1970-1900) ||
  384. b_time.tm_year == (1-1900));
  385. /* while unlikely, the system's gmtime(_r) could return
  386. * a "correct" retrospective gregorian negative year value,
  387. * which I'm pretty sure is:
  388. * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
  389. * 730485 is the number of days in two millenia, including leap days
  390. * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
  391. t_res = INT64_MIN;
  392. tor_gmtime_r(&t_res, &b_time);
  393. tt_assert(b_time.tm_year == (1970-1900) ||
  394. b_time.tm_year == (1-1900));
  395. }
  396. #endif
  397. /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
  398. * depending on whether the implementation of the system gmtime(_r)
  399. * sets struct tm (9999) or not (2037) */
  400. #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
  401. {
  402. t_res = 3*(1 << 29);
  403. tor_gmtime_r(&t_res, &b_time);
  404. tt_assert(b_time.tm_year == (2021-1900));
  405. t_res = INT32_MAX;
  406. tor_gmtime_r(&t_res, &b_time);
  407. tt_assert(b_time.tm_year == (2037-1900) ||
  408. b_time.tm_year == (2038-1900));
  409. }
  410. #endif
  411. #if SIZEOF_TIME_T == 8
  412. {
  413. /* one of the largest tm_year values my 64 bit system supports:
  414. * b_time.tm_year == (292278994L-1900L) without clamping */
  415. t_res = 9223372036854775LL;
  416. tor_gmtime_r(&t_res, &b_time);
  417. tt_assert(b_time.tm_year == (2037-1900) ||
  418. b_time.tm_year == (9999-1900));
  419. /* while unlikely, the system's gmtime(_r) could return
  420. * a "correct" proleptic gregorian year value,
  421. * which I'm pretty sure is:
  422. * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
  423. * 730485 is the number of days in two millenia, including leap days
  424. * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
  425. t_res = INT64_MAX;
  426. tor_gmtime_r(&t_res, &b_time);
  427. tt_assert(b_time.tm_year == (2037-1900) ||
  428. b_time.tm_year == (9999-1900));
  429. }
  430. #endif
  431. /* Test {format,parse}_rfc1123_time */
  432. format_rfc1123_time(timestr, 0);
  433. tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ, timestr);
  434. format_rfc1123_time(timestr, (time_t)1091580502UL);
  435. tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ, timestr);
  436. t_res = 0;
  437. i = parse_rfc1123_time(timestr, &t_res);
  438. tt_int_op(0,OP_EQ, i);
  439. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  440. /* The timezone doesn't matter */
  441. t_res = 0;
  442. tt_int_op(0,OP_EQ,
  443. parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res));
  444. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  445. tt_int_op(-1,OP_EQ,
  446. parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
  447. tt_int_op(-1,OP_EQ,
  448. parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res));
  449. tt_int_op(-1,OP_EQ,
  450. parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res));
  451. tt_int_op(-1,OP_EQ,
  452. parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res));
  453. tt_int_op(-1,OP_EQ,
  454. parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res));
  455. tt_int_op(-1,OP_EQ,
  456. parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res));
  457. tt_int_op(-1,OP_EQ,
  458. parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res));
  459. tt_int_op(-1,OP_EQ,
  460. parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res));
  461. tt_int_op(-1,OP_EQ,
  462. parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res));
  463. tt_int_op(-1,OP_EQ,
  464. parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res));
  465. /* Test parse_iso_time */
  466. t_res = 0;
  467. i = parse_iso_time("", &t_res);
  468. tt_int_op(-1,OP_EQ, i);
  469. t_res = 0;
  470. i = parse_iso_time("2004-08-32 00:48:22", &t_res);
  471. tt_int_op(-1,OP_EQ, i);
  472. t_res = 0;
  473. i = parse_iso_time("1969-08-03 00:48:22", &t_res);
  474. tt_int_op(-1,OP_EQ, i);
  475. t_res = 0;
  476. i = parse_iso_time("2004-08-04 00:48:22", &t_res);
  477. tt_int_op(0,OP_EQ, i);
  478. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  479. t_res = 0;
  480. i = parse_iso_time("2004-8-4 0:48:22", &t_res);
  481. tt_int_op(0,OP_EQ, i);
  482. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  483. tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-zz 99-99x99", &t_res));
  484. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-32 00:00:00", &t_res));
  485. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 24:00:00", &t_res));
  486. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:60:00", &t_res));
  487. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59:62", &t_res));
  488. tt_int_op(-1,OP_EQ, parse_iso_time("1969-03-30 23:59:59", &t_res));
  489. tt_int_op(-1,OP_EQ, parse_iso_time("2011-00-30 23:59:59", &t_res));
  490. tt_int_op(-1,OP_EQ, parse_iso_time("2147483647-08-29 14:00:00", &t_res));
  491. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59", &t_res));
  492. tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22.100", &t_res));
  493. tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res));
  494. /* Test tor_gettimeofday */
  495. end.tv_sec = 4;
  496. end.tv_usec = 999990;
  497. start.tv_sec = 1;
  498. start.tv_usec = 500;
  499. tor_gettimeofday(&start);
  500. /* now make sure time works. */
  501. tor_gettimeofday(&end);
  502. /* We might've timewarped a little. */
  503. tt_int_op(tv_udiff(&start, &end), OP_GE, -5000);
  504. /* Test format_iso_time */
  505. tv.tv_sec = (time_t)1326296338;
  506. tv.tv_usec = 3060;
  507. format_iso_time(timestr, (time_t)tv.tv_sec);
  508. tt_str_op("2012-01-11 15:38:58",OP_EQ, timestr);
  509. /* The output of format_local_iso_time will vary by timezone, and setting
  510. our timezone for testing purposes would be a nontrivial flaky pain.
  511. Skip this test for now.
  512. format_local_iso_time(timestr, tv.tv_sec);
  513. test_streq("2012-01-11 10:38:58", timestr);
  514. */
  515. format_iso_time_nospace(timestr, (time_t)tv.tv_sec);
  516. tt_str_op("2012-01-11T15:38:58",OP_EQ, timestr);
  517. tt_int_op(strlen(timestr),OP_EQ, ISO_TIME_LEN);
  518. format_iso_time_nospace_usec(timestr, &tv);
  519. tt_str_op("2012-01-11T15:38:58.003060",OP_EQ, timestr);
  520. tt_int_op(strlen(timestr),OP_EQ, ISO_TIME_USEC_LEN);
  521. done:
  522. ;
  523. }
  524. static void
  525. test_util_parse_http_time(void *arg)
  526. {
  527. struct tm a_time;
  528. char b[ISO_TIME_LEN+1];
  529. (void)arg;
  530. #define T(s) do { \
  531. format_iso_time(b, tor_timegm(&a_time)); \
  532. tt_str_op(b, OP_EQ, (s)); \
  533. b[0]='\0'; \
  534. } while (0)
  535. /* Test parse_http_time */
  536. tt_int_op(-1,OP_EQ,
  537. parse_http_time("", &a_time));
  538. tt_int_op(-1,OP_EQ,
  539. parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time));
  540. tt_int_op(-1,OP_EQ,
  541. parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time));
  542. tt_int_op(-1,OP_EQ,
  543. parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time));
  544. tt_int_op(-1,OP_EQ,
  545. parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time));
  546. tt_int_op(-1,OP_EQ,
  547. parse_http_time("Sunday, August the third", &a_time));
  548. tt_int_op(-1,OP_EQ,
  549. parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time));
  550. tt_int_op(0,OP_EQ,
  551. parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time));
  552. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  553. T("1994-08-04 00:48:22");
  554. tt_int_op(0,OP_EQ,
  555. parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time));
  556. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  557. T("1994-08-04 00:48:22");
  558. tt_int_op(0,OP_EQ,
  559. parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time));
  560. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  561. T("1994-08-04 00:48:22");
  562. tt_int_op(0,OP_EQ,
  563. parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time));
  564. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  565. T("1994-08-04 00:48:22");
  566. tt_int_op(0,OP_EQ,
  567. parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time));
  568. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  569. T("1994-08-04 00:48:22");
  570. tt_int_op(0,OP_EQ,
  571. parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time));
  572. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  573. T("1994-08-04 00:48:22");
  574. tt_int_op(0,OP_EQ, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time));
  575. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  576. T("1994-08-04 00:48:22");
  577. tt_int_op(0,OP_EQ, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time));
  578. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  579. T("1994-08-04 00:48:22");
  580. tt_int_op(0,OP_EQ, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time));
  581. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  582. T("1994-08-04 00:48:22");
  583. tt_int_op(0,OP_EQ,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time));
  584. tt_int_op((time_t)1325376000UL,OP_EQ, tor_timegm(&a_time));
  585. T("2012-01-01 00:00:00");
  586. tt_int_op(0,OP_EQ,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time));
  587. tt_int_op((time_t)1356912000UL,OP_EQ, tor_timegm(&a_time));
  588. T("2012-12-31 00:00:00");
  589. tt_int_op(-1,OP_EQ, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time));
  590. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-32 00:00:00 GMT", &a_time));
  591. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 24:00:00 GMT", &a_time));
  592. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:60:00 GMT", &a_time));
  593. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:59:62 GMT", &a_time));
  594. tt_int_op(-1,OP_EQ, parse_http_time("1969-03-30 23:59:59 GMT", &a_time));
  595. tt_int_op(-1,OP_EQ, parse_http_time("2011-00-30 23:59:59 GMT", &a_time));
  596. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:59", &a_time));
  597. #undef T
  598. done:
  599. ;
  600. }
  601. static void
  602. test_util_config_line(void *arg)
  603. {
  604. char buf[1024];
  605. char *k=NULL, *v=NULL;
  606. const char *str;
  607. /* Test parse_config_line_from_str */
  608. (void)arg;
  609. strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n"
  610. "k2\n"
  611. "k3 \n" "\n" " \n" "#comment\n"
  612. "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
  613. "kseven \"a quoted 'string\"\n"
  614. "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
  615. "k9 a line that\\\n spans two lines.\n\n"
  616. "k10 more than\\\n one contin\\\nuation\n"
  617. "k11 \\\ncontinuation at the start\n"
  618. "k12 line with a\\\n#comment\n embedded\n"
  619. "k13\\\ncontinuation at the very start\n"
  620. "k14 a line that has a comment and # ends with a slash \\\n"
  621. "k15 this should be the next new line\n"
  622. "k16 a line that has a comment and # ends without a slash \n"
  623. "k17 this should be the next new line\n"
  624. , sizeof(buf));
  625. str = buf;
  626. str = parse_config_line_from_str(str, &k, &v);
  627. tt_str_op(k,OP_EQ, "k");
  628. tt_str_op(v,OP_EQ, "v");
  629. tor_free(k); tor_free(v);
  630. tt_assert(!strcmpstart(str, "key value with"));
  631. str = parse_config_line_from_str(str, &k, &v);
  632. tt_str_op(k,OP_EQ, "key");
  633. tt_str_op(v,OP_EQ, "value with spaces");
  634. tor_free(k); tor_free(v);
  635. tt_assert(!strcmpstart(str, "keykey"));
  636. str = parse_config_line_from_str(str, &k, &v);
  637. tt_str_op(k,OP_EQ, "keykey");
  638. tt_str_op(v,OP_EQ, "val");
  639. tor_free(k); tor_free(v);
  640. tt_assert(!strcmpstart(str, "k2\n"));
  641. str = parse_config_line_from_str(str, &k, &v);
  642. tt_str_op(k,OP_EQ, "k2");
  643. tt_str_op(v,OP_EQ, "");
  644. tor_free(k); tor_free(v);
  645. tt_assert(!strcmpstart(str, "k3 \n"));
  646. str = parse_config_line_from_str(str, &k, &v);
  647. tt_str_op(k,OP_EQ, "k3");
  648. tt_str_op(v,OP_EQ, "");
  649. tor_free(k); tor_free(v);
  650. tt_assert(!strcmpstart(str, "#comment"));
  651. str = parse_config_line_from_str(str, &k, &v);
  652. tt_str_op(k,OP_EQ, "k4");
  653. tt_str_op(v,OP_EQ, "");
  654. tor_free(k); tor_free(v);
  655. tt_assert(!strcmpstart(str, "k5#abc"));
  656. str = parse_config_line_from_str(str, &k, &v);
  657. tt_str_op(k,OP_EQ, "k5");
  658. tt_str_op(v,OP_EQ, "");
  659. tor_free(k); tor_free(v);
  660. tt_assert(!strcmpstart(str, "k6"));
  661. str = parse_config_line_from_str(str, &k, &v);
  662. tt_str_op(k,OP_EQ, "k6");
  663. tt_str_op(v,OP_EQ, "val");
  664. tor_free(k); tor_free(v);
  665. tt_assert(!strcmpstart(str, "kseven"));
  666. str = parse_config_line_from_str(str, &k, &v);
  667. tt_str_op(k,OP_EQ, "kseven");
  668. tt_str_op(v,OP_EQ, "a quoted \'string");
  669. tor_free(k); tor_free(v);
  670. tt_assert(!strcmpstart(str, "k8 "));
  671. str = parse_config_line_from_str(str, &k, &v);
  672. tt_str_op(k,OP_EQ, "k8");
  673. tt_str_op(v,OP_EQ, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
  674. tor_free(k); tor_free(v);
  675. str = parse_config_line_from_str(str, &k, &v);
  676. tt_str_op(k,OP_EQ, "k9");
  677. tt_str_op(v,OP_EQ, "a line that spans two lines.");
  678. tor_free(k); tor_free(v);
  679. str = parse_config_line_from_str(str, &k, &v);
  680. tt_str_op(k,OP_EQ, "k10");
  681. tt_str_op(v,OP_EQ, "more than one continuation");
  682. tor_free(k); tor_free(v);
  683. str = parse_config_line_from_str(str, &k, &v);
  684. tt_str_op(k,OP_EQ, "k11");
  685. tt_str_op(v,OP_EQ, "continuation at the start");
  686. tor_free(k); tor_free(v);
  687. str = parse_config_line_from_str(str, &k, &v);
  688. tt_str_op(k,OP_EQ, "k12");
  689. tt_str_op(v,OP_EQ, "line with a embedded");
  690. tor_free(k); tor_free(v);
  691. str = parse_config_line_from_str(str, &k, &v);
  692. tt_str_op(k,OP_EQ, "k13");
  693. tt_str_op(v,OP_EQ, "continuation at the very start");
  694. tor_free(k); tor_free(v);
  695. str = parse_config_line_from_str(str, &k, &v);
  696. tt_str_op(k,OP_EQ, "k14");
  697. tt_str_op(v,OP_EQ, "a line that has a comment and" );
  698. tor_free(k); tor_free(v);
  699. str = parse_config_line_from_str(str, &k, &v);
  700. tt_str_op(k,OP_EQ, "k15");
  701. tt_str_op(v,OP_EQ, "this should be the next new line");
  702. tor_free(k); tor_free(v);
  703. str = parse_config_line_from_str(str, &k, &v);
  704. tt_str_op(k,OP_EQ, "k16");
  705. tt_str_op(v,OP_EQ, "a line that has a comment and" );
  706. tor_free(k); tor_free(v);
  707. str = parse_config_line_from_str(str, &k, &v);
  708. tt_str_op(k,OP_EQ, "k17");
  709. tt_str_op(v,OP_EQ, "this should be the next new line");
  710. tor_free(k); tor_free(v);
  711. tt_str_op(str,OP_EQ, "");
  712. done:
  713. tor_free(k);
  714. tor_free(v);
  715. }
  716. static void
  717. test_util_config_line_quotes(void *arg)
  718. {
  719. char buf1[1024];
  720. char buf2[128];
  721. char buf3[128];
  722. char buf4[128];
  723. char *k=NULL, *v=NULL;
  724. const char *str;
  725. /* Test parse_config_line_from_str */
  726. (void)arg;
  727. strlcpy(buf1, "kTrailingSpace \"quoted value\" \n"
  728. "kTrailingGarbage \"quoted value\"trailing garbage\n"
  729. , sizeof(buf1));
  730. strlcpy(buf2, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
  731. , sizeof(buf2));
  732. strlcpy(buf3, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
  733. , sizeof(buf3));
  734. strlcpy(buf4, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
  735. , sizeof(buf4));
  736. str = buf1;
  737. str = parse_config_line_from_str(str, &k, &v);
  738. tt_str_op(k,OP_EQ, "kTrailingSpace");
  739. tt_str_op(v,OP_EQ, "quoted value");
  740. tor_free(k); tor_free(v);
  741. str = parse_config_line_from_str(str, &k, &v);
  742. tt_ptr_op(str,OP_EQ, NULL);
  743. tor_free(k); tor_free(v);
  744. str = buf2;
  745. str = parse_config_line_from_str(str, &k, &v);
  746. tt_ptr_op(str,OP_EQ, NULL);
  747. tor_free(k); tor_free(v);
  748. str = buf3;
  749. str = parse_config_line_from_str(str, &k, &v);
  750. tt_ptr_op(str,OP_EQ, NULL);
  751. tor_free(k); tor_free(v);
  752. str = buf4;
  753. str = parse_config_line_from_str(str, &k, &v);
  754. tt_ptr_op(str,OP_EQ, NULL);
  755. tor_free(k); tor_free(v);
  756. done:
  757. tor_free(k);
  758. tor_free(v);
  759. }
  760. static void
  761. test_util_config_line_comment_character(void *arg)
  762. {
  763. char buf[1024];
  764. char *k=NULL, *v=NULL;
  765. const char *str;
  766. /* Test parse_config_line_from_str */
  767. (void)arg;
  768. strlcpy(buf, "k1 \"# in quotes\"\n"
  769. "k2 some value # some comment\n"
  770. "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
  771. , sizeof(buf));
  772. str = buf;
  773. str = parse_config_line_from_str(str, &k, &v);
  774. tt_str_op(k,OP_EQ, "k1");
  775. tt_str_op(v,OP_EQ, "# in quotes");
  776. tor_free(k); tor_free(v);
  777. str = parse_config_line_from_str(str, &k, &v);
  778. tt_str_op(k,OP_EQ, "k2");
  779. tt_str_op(v,OP_EQ, "some value");
  780. tor_free(k); tor_free(v);
  781. tt_str_op(str,OP_EQ, "k3 /home/user/myTorNetwork#2\n");
  782. #if 0
  783. str = parse_config_line_from_str(str, &k, &v);
  784. test_streq(k, "k3");
  785. test_streq(v, "/home/user/myTorNetwork#2");
  786. tor_free(k); tor_free(v);
  787. test_streq(str, "");
  788. #endif
  789. done:
  790. tor_free(k);
  791. tor_free(v);
  792. }
  793. static void
  794. test_util_config_line_escaped_content(void *arg)
  795. {
  796. char buf1[1024];
  797. char buf2[128];
  798. char buf3[128];
  799. char buf4[128];
  800. char buf5[128];
  801. char buf6[128];
  802. char *k=NULL, *v=NULL;
  803. const char *str;
  804. /* Test parse_config_line_from_str */
  805. (void)arg;
  806. strlcpy(buf1, "HexadecimalLower \"\\x2a\"\n"
  807. "HexadecimalUpper \"\\x2A\"\n"
  808. "HexadecimalUpperX \"\\X2A\"\n"
  809. "Octal \"\\52\"\n"
  810. "Newline \"\\n\"\n"
  811. "Tab \"\\t\"\n"
  812. "CarriageReturn \"\\r\"\n"
  813. "DoubleQuote \"\\\"\"\n"
  814. "SimpleQuote \"\\'\"\n"
  815. "Backslash \"\\\\\"\n"
  816. "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
  817. , sizeof(buf1));
  818. strlcpy(buf2, "BrokenEscapedContent \"\\a\"\n"
  819. , sizeof(buf2));
  820. strlcpy(buf3, "BrokenEscapedContent \"\\x\"\n"
  821. , sizeof(buf3));
  822. strlcpy(buf4, "BrokenOctal \"\\8\"\n"
  823. , sizeof(buf4));
  824. strlcpy(buf5, "BrokenHex \"\\xg4\"\n"
  825. , sizeof(buf5));
  826. strlcpy(buf6, "BrokenEscape \"\\"
  827. , sizeof(buf6));
  828. str = buf1;
  829. str = parse_config_line_from_str(str, &k, &v);
  830. tt_str_op(k,OP_EQ, "HexadecimalLower");
  831. tt_str_op(v,OP_EQ, "*");
  832. tor_free(k); tor_free(v);
  833. str = parse_config_line_from_str(str, &k, &v);
  834. tt_str_op(k,OP_EQ, "HexadecimalUpper");
  835. tt_str_op(v,OP_EQ, "*");
  836. tor_free(k); tor_free(v);
  837. str = parse_config_line_from_str(str, &k, &v);
  838. tt_str_op(k,OP_EQ, "HexadecimalUpperX");
  839. tt_str_op(v,OP_EQ, "*");
  840. tor_free(k); tor_free(v);
  841. str = parse_config_line_from_str(str, &k, &v);
  842. tt_str_op(k,OP_EQ, "Octal");
  843. tt_str_op(v,OP_EQ, "*");
  844. tor_free(k); tor_free(v);
  845. str = parse_config_line_from_str(str, &k, &v);
  846. tt_str_op(k,OP_EQ, "Newline");
  847. tt_str_op(v,OP_EQ, "\n");
  848. tor_free(k); tor_free(v);
  849. str = parse_config_line_from_str(str, &k, &v);
  850. tt_str_op(k,OP_EQ, "Tab");
  851. tt_str_op(v,OP_EQ, "\t");
  852. tor_free(k); tor_free(v);
  853. str = parse_config_line_from_str(str, &k, &v);
  854. tt_str_op(k,OP_EQ, "CarriageReturn");
  855. tt_str_op(v,OP_EQ, "\r");
  856. tor_free(k); tor_free(v);
  857. str = parse_config_line_from_str(str, &k, &v);
  858. tt_str_op(k,OP_EQ, "DoubleQuote");
  859. tt_str_op(v,OP_EQ, "\"");
  860. tor_free(k); tor_free(v);
  861. str = parse_config_line_from_str(str, &k, &v);
  862. tt_str_op(k,OP_EQ, "SimpleQuote");
  863. tt_str_op(v,OP_EQ, "'");
  864. tor_free(k); tor_free(v);
  865. str = parse_config_line_from_str(str, &k, &v);
  866. tt_str_op(k,OP_EQ, "Backslash");
  867. tt_str_op(v,OP_EQ, "\\");
  868. tor_free(k); tor_free(v);
  869. str = parse_config_line_from_str(str, &k, &v);
  870. tt_str_op(k,OP_EQ, "Mix");
  871. tt_str_op(v,OP_EQ, "This is a \"star\":\t'*'\nAnd second line");
  872. tor_free(k); tor_free(v);
  873. tt_str_op(str,OP_EQ, "");
  874. str = buf2;
  875. str = parse_config_line_from_str(str, &k, &v);
  876. tt_ptr_op(str,OP_EQ, NULL);
  877. tor_free(k); tor_free(v);
  878. str = buf3;
  879. str = parse_config_line_from_str(str, &k, &v);
  880. tt_ptr_op(str,OP_EQ, NULL);
  881. tor_free(k); tor_free(v);
  882. str = buf4;
  883. str = parse_config_line_from_str(str, &k, &v);
  884. tt_ptr_op(str,OP_EQ, NULL);
  885. tor_free(k); tor_free(v);
  886. #if 0
  887. str = buf5;
  888. str = parse_config_line_from_str(str, &k, &v);
  889. tt_ptr_op(str, OP_EQ, NULL);
  890. tor_free(k); tor_free(v);
  891. #endif
  892. str = buf6;
  893. str = parse_config_line_from_str(str, &k, &v);
  894. tt_ptr_op(str,OP_EQ, NULL);
  895. tor_free(k); tor_free(v);
  896. done:
  897. tor_free(k);
  898. tor_free(v);
  899. }
  900. #ifndef _WIN32
  901. static void
  902. test_util_expand_filename(void *arg)
  903. {
  904. char *str;
  905. (void)arg;
  906. setenv("HOME", "/home/itv", 1); /* For "internal test value" */
  907. str = expand_filename("");
  908. tt_str_op("",OP_EQ, str);
  909. tor_free(str);
  910. str = expand_filename("/normal/path");
  911. tt_str_op("/normal/path",OP_EQ, str);
  912. tor_free(str);
  913. str = expand_filename("/normal/trailing/path/");
  914. tt_str_op("/normal/trailing/path/",OP_EQ, str);
  915. tor_free(str);
  916. str = expand_filename("~");
  917. tt_str_op("/home/itv/",OP_EQ, str);
  918. tor_free(str);
  919. str = expand_filename("$HOME/nodice");
  920. tt_str_op("$HOME/nodice",OP_EQ, str);
  921. tor_free(str);
  922. str = expand_filename("~/");
  923. tt_str_op("/home/itv/",OP_EQ, str);
  924. tor_free(str);
  925. str = expand_filename("~/foobarqux");
  926. tt_str_op("/home/itv/foobarqux",OP_EQ, str);
  927. tor_free(str);
  928. str = expand_filename("~/../../etc/passwd");
  929. tt_str_op("/home/itv/../../etc/passwd",OP_EQ, str);
  930. tor_free(str);
  931. str = expand_filename("~/trailing/");
  932. tt_str_op("/home/itv/trailing/",OP_EQ, str);
  933. tor_free(str);
  934. /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
  935. have to somehow inject/fake the get_user_homedir call) */
  936. /* $HOME ending in a trailing slash */
  937. setenv("HOME", "/home/itv/", 1);
  938. str = expand_filename("~");
  939. tt_str_op("/home/itv/",OP_EQ, str);
  940. tor_free(str);
  941. str = expand_filename("~/");
  942. tt_str_op("/home/itv/",OP_EQ, str);
  943. tor_free(str);
  944. str = expand_filename("~/foo");
  945. tt_str_op("/home/itv/foo",OP_EQ, str);
  946. tor_free(str);
  947. /* Try with empty $HOME */
  948. setenv("HOME", "", 1);
  949. str = expand_filename("~");
  950. tt_str_op("/",OP_EQ, str);
  951. tor_free(str);
  952. str = expand_filename("~/");
  953. tt_str_op("/",OP_EQ, str);
  954. tor_free(str);
  955. str = expand_filename("~/foobar");
  956. tt_str_op("/foobar",OP_EQ, str);
  957. tor_free(str);
  958. /* Try with $HOME unset */
  959. unsetenv("HOME");
  960. str = expand_filename("~");
  961. tt_str_op("/",OP_EQ, str);
  962. tor_free(str);
  963. str = expand_filename("~/");
  964. tt_str_op("/",OP_EQ, str);
  965. tor_free(str);
  966. str = expand_filename("~/foobar");
  967. tt_str_op("/foobar",OP_EQ, str);
  968. tor_free(str);
  969. done:
  970. tor_free(str);
  971. }
  972. #endif
  973. /** Test tor_escape_str_for_pt_args(). */
  974. static void
  975. test_util_escape_string_socks(void *arg)
  976. {
  977. char *escaped_string = NULL;
  978. /** Simple backslash escape. */
  979. (void)arg;
  980. escaped_string = tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
  981. tt_assert(escaped_string);
  982. tt_str_op(escaped_string,OP_EQ, "This is a backslash: \\\\");
  983. tor_free(escaped_string);
  984. /** Simple semicolon escape. */
  985. escaped_string = tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
  986. tt_assert(escaped_string);
  987. tt_str_op(escaped_string,OP_EQ, "First rule:Do not use \\;");
  988. tor_free(escaped_string);
  989. /** Empty string. */
  990. escaped_string = tor_escape_str_for_pt_args("", ";\\");
  991. tt_assert(escaped_string);
  992. tt_str_op(escaped_string,OP_EQ, "");
  993. tor_free(escaped_string);
  994. /** Escape all characters. */
  995. escaped_string = tor_escape_str_for_pt_args(";\\;\\", ";\\");
  996. tt_assert(escaped_string);
  997. tt_str_op(escaped_string,OP_EQ, "\\;\\\\\\;\\\\");
  998. tor_free(escaped_string);
  999. escaped_string = tor_escape_str_for_pt_args(";", ";\\");
  1000. tt_assert(escaped_string);
  1001. tt_str_op(escaped_string,OP_EQ, "\\;");
  1002. tor_free(escaped_string);
  1003. done:
  1004. tor_free(escaped_string);
  1005. }
  1006. static void
  1007. test_util_string_is_key_value(void *ptr)
  1008. {
  1009. (void)ptr;
  1010. tt_assert(string_is_key_value(LOG_WARN, "key=value"));
  1011. tt_assert(string_is_key_value(LOG_WARN, "k=v"));
  1012. tt_assert(string_is_key_value(LOG_WARN, "key="));
  1013. tt_assert(string_is_key_value(LOG_WARN, "x="));
  1014. tt_assert(string_is_key_value(LOG_WARN, "xx="));
  1015. tt_assert(!string_is_key_value(LOG_WARN, "=value"));
  1016. tt_assert(!string_is_key_value(LOG_WARN, "=x"));
  1017. tt_assert(!string_is_key_value(LOG_WARN, "="));
  1018. /* ??? */
  1019. /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
  1020. done:
  1021. ;
  1022. }
  1023. /** Test basic string functionality. */
  1024. static void
  1025. test_util_strmisc(void *arg)
  1026. {
  1027. char buf[1024];
  1028. int i;
  1029. char *cp, *cp_tmp = NULL;
  1030. /* Test strl operations */
  1031. (void)arg;
  1032. tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 0));
  1033. tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 10));
  1034. tt_str_op(buf,OP_EQ, "Hello");
  1035. tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 6));
  1036. tt_str_op(buf,OP_EQ, "Hello");
  1037. tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 5));
  1038. tt_str_op(buf,OP_EQ, "Hell");
  1039. strlcpy(buf, "Hello", sizeof(buf));
  1040. tt_int_op(10,OP_EQ, strlcat(buf, "Hello", 5));
  1041. /* Test strstrip() */
  1042. strlcpy(buf, "Testing 1 2 3", sizeof(buf));
  1043. tor_strstrip(buf, ",!");
  1044. tt_str_op(buf,OP_EQ, "Testing 1 2 3");
  1045. strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
  1046. tor_strstrip(buf, "!? ");
  1047. tt_str_op(buf,OP_EQ, "Testing123");
  1048. strlcpy(buf, "!!!Testing 1 2 3??", sizeof(buf));
  1049. tor_strstrip(buf, "!? ");
  1050. tt_str_op(buf,OP_EQ, "Testing123");
  1051. /* Test parse_long */
  1052. /* Empty/zero input */
  1053. tt_int_op(0L,OP_EQ, tor_parse_long("",10,0,100,&i,NULL));
  1054. tt_int_op(0,OP_EQ, i);
  1055. tt_int_op(0L,OP_EQ, tor_parse_long("0",10,0,100,&i,NULL));
  1056. tt_int_op(1,OP_EQ, i);
  1057. /* Normal cases */
  1058. tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,100,&i,NULL));
  1059. tt_int_op(1,OP_EQ, i);
  1060. tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,10,&i,NULL));
  1061. tt_int_op(1,OP_EQ, i);
  1062. tt_int_op(10L,OP_EQ, tor_parse_long("10",10,10,100,&i,NULL));
  1063. tt_int_op(1,OP_EQ, i);
  1064. tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,100,&i,NULL));
  1065. tt_int_op(1,OP_EQ, i);
  1066. tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,0,&i,NULL));
  1067. tt_int_op(1,OP_EQ, i);
  1068. tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-50,0,&i,NULL));
  1069. tt_int_op(1,OP_EQ, i);
  1070. /* Extra garbage */
  1071. tt_int_op(0L,OP_EQ, tor_parse_long("10m",10,0,100,&i,NULL));
  1072. tt_int_op(0,OP_EQ, i);
  1073. tt_int_op(0L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
  1074. tt_int_op(0,OP_EQ, i);
  1075. tt_int_op(10L,OP_EQ, tor_parse_long("10m",10,0,100,&i,&cp));
  1076. tt_int_op(1,OP_EQ, i);
  1077. tt_str_op(cp,OP_EQ, "m");
  1078. tt_int_op(-50L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
  1079. tt_int_op(1,OP_EQ, i);
  1080. tt_str_op(cp,OP_EQ, " plus garbage");
  1081. /* Out of bounds */
  1082. tt_int_op(0L,OP_EQ, tor_parse_long("10",10,50,100,&i,NULL));
  1083. tt_int_op(0,OP_EQ, i);
  1084. tt_int_op(0L,OP_EQ, tor_parse_long("-50",10,0,100,&i,NULL));
  1085. tt_int_op(0,OP_EQ, i);
  1086. /* Base different than 10 */
  1087. tt_int_op(2L,OP_EQ, tor_parse_long("10",2,0,100,NULL,NULL));
  1088. tt_int_op(0L,OP_EQ, tor_parse_long("2",2,0,100,NULL,NULL));
  1089. tt_int_op(0L,OP_EQ, tor_parse_long("10",-2,0,100,NULL,NULL));
  1090. tt_int_op(68284L,OP_EQ, tor_parse_long("10abc",16,0,70000,NULL,NULL));
  1091. tt_int_op(68284L,OP_EQ, tor_parse_long("10ABC",16,0,70000,NULL,NULL));
  1092. tt_int_op(0,OP_EQ, tor_parse_long("10ABC",-1,0,70000,&i,NULL));
  1093. tt_int_op(i,OP_EQ, 0);
  1094. /* Test parse_ulong */
  1095. tt_int_op(0UL,OP_EQ, tor_parse_ulong("",10,0,100,NULL,NULL));
  1096. tt_int_op(0UL,OP_EQ, tor_parse_ulong("0",10,0,100,NULL,NULL));
  1097. tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,100,NULL,NULL));
  1098. tt_int_op(0UL,OP_EQ, tor_parse_ulong("10",10,50,100,NULL,NULL));
  1099. tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,10,NULL,NULL));
  1100. tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,10,100,NULL,NULL));
  1101. tt_int_op(0UL,OP_EQ, tor_parse_ulong("8",8,0,100,NULL,NULL));
  1102. tt_int_op(50UL,OP_EQ, tor_parse_ulong("50",10,50,100,NULL,NULL));
  1103. tt_int_op(0UL,OP_EQ, tor_parse_ulong("-50",10,-100,100,NULL,NULL));
  1104. tt_int_op(0UL,OP_EQ, tor_parse_ulong("50",-1,50,100,&i,NULL));
  1105. tt_int_op(0,OP_EQ, i);
  1106. /* Test parse_uint64 */
  1107. tt_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
  1108. tt_int_op(1,OP_EQ, i);
  1109. tt_str_op(cp,OP_EQ, " x");
  1110. tt_assert(U64_LITERAL(12345678901) ==
  1111. tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
  1112. tt_int_op(1,OP_EQ, i);
  1113. tt_str_op(cp,OP_EQ, "");
  1114. tt_assert(U64_LITERAL(0) ==
  1115. tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
  1116. tt_int_op(0,OP_EQ, i);
  1117. tt_assert(U64_LITERAL(0) ==
  1118. tor_parse_uint64("123",-1,0,INT32_MAX, &i, &cp));
  1119. tt_int_op(0,OP_EQ, i);
  1120. {
  1121. /* Test parse_double */
  1122. double d = tor_parse_double("10", 0, UINT64_MAX,&i,NULL);
  1123. tt_int_op(1,OP_EQ, i);
  1124. tt_assert(DBL_TO_U64(d) == 10);
  1125. d = tor_parse_double("0", 0, UINT64_MAX,&i,NULL);
  1126. tt_int_op(1,OP_EQ, i);
  1127. tt_assert(DBL_TO_U64(d) == 0);
  1128. d = tor_parse_double(" ", 0, UINT64_MAX,&i,NULL);
  1129. tt_int_op(0,OP_EQ, i);
  1130. d = tor_parse_double(".0a", 0, UINT64_MAX,&i,NULL);
  1131. tt_int_op(0,OP_EQ, i);
  1132. d = tor_parse_double(".0a", 0, UINT64_MAX,&i,&cp);
  1133. tt_int_op(1,OP_EQ, i);
  1134. d = tor_parse_double("-.0", 0, UINT64_MAX,&i,NULL);
  1135. tt_int_op(1,OP_EQ, i);
  1136. tt_assert(DBL_TO_U64(d) == 0);
  1137. d = tor_parse_double("-10", -100.0, 100.0,&i,NULL);
  1138. tt_int_op(1,OP_EQ, i);
  1139. tt_int_op(-10.0,OP_EQ, d);
  1140. }
  1141. {
  1142. /* Test tor_parse_* where we overflow/underflow the underlying type. */
  1143. /* This string should overflow 64-bit ints. */
  1144. #define TOOBIG "100000000000000000000000000"
  1145. tt_int_op(0L, OP_EQ,
  1146. tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
  1147. tt_int_op(i,OP_EQ, 0);
  1148. tt_int_op(0L,OP_EQ,
  1149. tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
  1150. tt_int_op(i,OP_EQ, 0);
  1151. tt_int_op(0UL,OP_EQ, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
  1152. tt_int_op(i,OP_EQ, 0);
  1153. tt_u64_op(U64_LITERAL(0), OP_EQ, tor_parse_uint64(TOOBIG, 10,
  1154. 0, UINT64_MAX, &i, NULL));
  1155. tt_int_op(i,OP_EQ, 0);
  1156. }
  1157. /* Test snprintf */
  1158. /* Returning -1 when there's not enough room in the output buffer */
  1159. tt_int_op(-1,OP_EQ, tor_snprintf(buf, 0, "Foo"));
  1160. tt_int_op(-1,OP_EQ, tor_snprintf(buf, 2, "Foo"));
  1161. tt_int_op(-1,OP_EQ, tor_snprintf(buf, 3, "Foo"));
  1162. tt_int_op(-1,OP_NE, tor_snprintf(buf, 4, "Foo"));
  1163. /* Always NUL-terminate the output */
  1164. tor_snprintf(buf, 5, "abcdef");
  1165. tt_int_op(0,OP_EQ, buf[4]);
  1166. tor_snprintf(buf, 10, "abcdef");
  1167. tt_int_op(0,OP_EQ, buf[6]);
  1168. /* uint64 */
  1169. tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
  1170. U64_PRINTF_ARG(U64_LITERAL(12345678901)));
  1171. tt_str_op("x!12345678901!x",OP_EQ, buf);
  1172. /* Test str{,case}cmpstart */
  1173. tt_assert(strcmpstart("abcdef", "abcdef")==0);
  1174. tt_assert(strcmpstart("abcdef", "abc")==0);
  1175. tt_assert(strcmpstart("abcdef", "abd")<0);
  1176. tt_assert(strcmpstart("abcdef", "abb")>0);
  1177. tt_assert(strcmpstart("ab", "abb")<0);
  1178. tt_assert(strcmpstart("ab", "")==0);
  1179. tt_assert(strcmpstart("ab", "ab ")<0);
  1180. tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
  1181. tt_assert(strcasecmpstart("abcDeF", "abc")==0);
  1182. tt_assert(strcasecmpstart("abcdef", "Abd")<0);
  1183. tt_assert(strcasecmpstart("Abcdef", "abb")>0);
  1184. tt_assert(strcasecmpstart("ab", "Abb")<0);
  1185. tt_assert(strcasecmpstart("ab", "")==0);
  1186. tt_assert(strcasecmpstart("ab", "ab ")<0);
  1187. /* Test str{,case}cmpend */
  1188. tt_assert(strcmpend("abcdef", "abcdef")==0);
  1189. tt_assert(strcmpend("abcdef", "def")==0);
  1190. tt_assert(strcmpend("abcdef", "deg")<0);
  1191. tt_assert(strcmpend("abcdef", "dee")>0);
  1192. tt_assert(strcmpend("ab", "aab")>0);
  1193. tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
  1194. tt_assert(strcasecmpend("abcdef", "dEF")==0);
  1195. tt_assert(strcasecmpend("abcdef", "Deg")<0);
  1196. tt_assert(strcasecmpend("abcDef", "dee")>0);
  1197. tt_assert(strcasecmpend("AB", "abb")<0);
  1198. /* Test digest_is_zero */
  1199. memset(buf,0,20);
  1200. buf[20] = 'x';
  1201. tt_assert(tor_digest_is_zero(buf));
  1202. buf[19] = 'x';
  1203. tt_assert(!tor_digest_is_zero(buf));
  1204. /* Test mem_is_zero */
  1205. memset(buf,0,128);
  1206. buf[128] = 'x';
  1207. tt_assert(tor_mem_is_zero(buf, 10));
  1208. tt_assert(tor_mem_is_zero(buf, 20));
  1209. tt_assert(tor_mem_is_zero(buf, 128));
  1210. tt_assert(!tor_mem_is_zero(buf, 129));
  1211. buf[60] = (char)255;
  1212. tt_assert(!tor_mem_is_zero(buf, 128));
  1213. buf[0] = (char)1;
  1214. tt_assert(!tor_mem_is_zero(buf, 10));
  1215. /* Test 'escaped' */
  1216. tt_assert(NULL == escaped(NULL));
  1217. tt_str_op("\"\"",OP_EQ, escaped(""));
  1218. tt_str_op("\"abcd\"",OP_EQ, escaped("abcd"));
  1219. tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ, escaped("\\ \n\r\t\"'"));
  1220. tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ,
  1221. escaped("unnecessary \'backslashes\'"));
  1222. /* Non-printable characters appear as octal */
  1223. tt_str_op("\"z\\001abc\\277d\"",OP_EQ, escaped("z\001abc\277d"));
  1224. tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ, escaped("z\xde\xad\x20;foo"));
  1225. /* Test strndup and memdup */
  1226. {
  1227. const char *s = "abcdefghijklmnopqrstuvwxyz";
  1228. cp_tmp = tor_strndup(s, 30);
  1229. tt_str_op(cp_tmp,OP_EQ, s); /* same string, */
  1230. tt_ptr_op(cp_tmp,OP_NE,s); /* but different pointers. */
  1231. tor_free(cp_tmp);
  1232. cp_tmp = tor_strndup(s, 5);
  1233. tt_str_op(cp_tmp,OP_EQ, "abcde");
  1234. tor_free(cp_tmp);
  1235. s = "a\0b\0c\0d\0e\0";
  1236. cp_tmp = tor_memdup(s,10);
  1237. tt_mem_op(cp_tmp,OP_EQ, s, 10); /* same ram, */
  1238. tt_ptr_op(cp_tmp,OP_NE,s); /* but different pointers. */
  1239. tor_free(cp_tmp);
  1240. }
  1241. /* Test str-foo functions */
  1242. cp_tmp = tor_strdup("abcdef");
  1243. tt_assert(tor_strisnonupper(cp_tmp));
  1244. cp_tmp[3] = 'D';
  1245. tt_assert(!tor_strisnonupper(cp_tmp));
  1246. tor_strupper(cp_tmp);
  1247. tt_str_op(cp_tmp,OP_EQ, "ABCDEF");
  1248. tor_strlower(cp_tmp);
  1249. tt_str_op(cp_tmp,OP_EQ, "abcdef");
  1250. tt_assert(tor_strisnonupper(cp_tmp));
  1251. tt_assert(tor_strisprint(cp_tmp));
  1252. cp_tmp[3] = 3;
  1253. tt_assert(!tor_strisprint(cp_tmp));
  1254. tor_free(cp_tmp);
  1255. /* Test memmem and memstr */
  1256. {
  1257. const char *haystack = "abcde";
  1258. tt_assert(!tor_memmem(haystack, 5, "ef", 2));
  1259. tt_ptr_op(tor_memmem(haystack, 5, "cd", 2),OP_EQ, haystack + 2);
  1260. tt_ptr_op(tor_memmem(haystack, 5, "cde", 3),OP_EQ, haystack + 2);
  1261. tt_assert(!tor_memmem(haystack, 4, "cde", 3));
  1262. haystack = "ababcad";
  1263. tt_ptr_op(tor_memmem(haystack, 7, "abc", 3),OP_EQ, haystack + 2);
  1264. tt_ptr_op(tor_memmem(haystack, 7, "ad", 2),OP_EQ, haystack + 5);
  1265. tt_ptr_op(tor_memmem(haystack, 7, "cad", 3),OP_EQ, haystack + 4);
  1266. tt_assert(!tor_memmem(haystack, 7, "dadad", 5));
  1267. tt_assert(!tor_memmem(haystack, 7, "abcdefghij", 10));
  1268. /* memstr */
  1269. tt_ptr_op(tor_memstr(haystack, 7, "abc"),OP_EQ, haystack + 2);
  1270. tt_ptr_op(tor_memstr(haystack, 7, "cad"),OP_EQ, haystack + 4);
  1271. tt_assert(!tor_memstr(haystack, 6, "cad"));
  1272. tt_assert(!tor_memstr(haystack, 7, "cadd"));
  1273. tt_assert(!tor_memstr(haystack, 7, "fe"));
  1274. tt_assert(!tor_memstr(haystack, 7, "ababcade"));
  1275. }
  1276. /* Test hex_str */
  1277. {
  1278. char binary_data[68];
  1279. size_t i;
  1280. for (i = 0; i < sizeof(binary_data); ++i)
  1281. binary_data[i] = i;
  1282. tt_str_op(hex_str(binary_data, 0),OP_EQ, "");
  1283. tt_str_op(hex_str(binary_data, 1),OP_EQ, "00");
  1284. tt_str_op(hex_str(binary_data, 17),OP_EQ,
  1285. "000102030405060708090A0B0C0D0E0F10");
  1286. tt_str_op(hex_str(binary_data, 32),OP_EQ,
  1287. "000102030405060708090A0B0C0D0E0F"
  1288. "101112131415161718191A1B1C1D1E1F");
  1289. tt_str_op(hex_str(binary_data, 34),OP_EQ,
  1290. "000102030405060708090A0B0C0D0E0F"
  1291. "101112131415161718191A1B1C1D1E1F");
  1292. /* Repeat these tests for shorter strings after longer strings
  1293. have been tried, to make sure we're correctly terminating strings */
  1294. tt_str_op(hex_str(binary_data, 1),OP_EQ, "00");
  1295. tt_str_op(hex_str(binary_data, 0),OP_EQ, "");
  1296. }
  1297. /* Test strcmp_opt */
  1298. tt_int_op(strcmp_opt("", "foo"), OP_LT, 0);
  1299. tt_int_op(strcmp_opt("", ""), OP_EQ, 0);
  1300. tt_int_op(strcmp_opt("foo", ""), OP_GT, 0);
  1301. tt_int_op(strcmp_opt(NULL, ""), OP_LT, 0);
  1302. tt_int_op(strcmp_opt(NULL, NULL), OP_EQ, 0);
  1303. tt_int_op(strcmp_opt("", NULL), OP_GT, 0);
  1304. tt_int_op(strcmp_opt(NULL, "foo"), OP_LT, 0);
  1305. tt_int_op(strcmp_opt("foo", NULL), OP_GT, 0);
  1306. /* Test strcmp_len */
  1307. tt_int_op(strcmp_len("foo", "bar", 3), OP_GT, 0);
  1308. tt_int_op(strcmp_len("foo", "bar", 2), OP_LT, 0);
  1309. tt_int_op(strcmp_len("foo2", "foo1", 4), OP_GT, 0);
  1310. tt_int_op(strcmp_len("foo2", "foo1", 3), OP_LT, 0); /* Really stop at len */
  1311. tt_int_op(strcmp_len("foo2", "foo", 3), OP_EQ, 0); /* Really stop at len */
  1312. tt_int_op(strcmp_len("blah", "", 4), OP_GT, 0);
  1313. tt_int_op(strcmp_len("blah", "", 0), OP_EQ, 0);
  1314. done:
  1315. tor_free(cp_tmp);
  1316. }
  1317. static void
  1318. test_util_pow2(void *arg)
  1319. {
  1320. /* Test tor_log2(). */
  1321. (void)arg;
  1322. tt_int_op(tor_log2(64),OP_EQ, 6);
  1323. tt_int_op(tor_log2(65),OP_EQ, 6);
  1324. tt_int_op(tor_log2(63),OP_EQ, 5);
  1325. /* incorrect mathematically, but as specified: */
  1326. tt_int_op(tor_log2(0),OP_EQ, 0);
  1327. tt_int_op(tor_log2(1),OP_EQ, 0);
  1328. tt_int_op(tor_log2(2),OP_EQ, 1);
  1329. tt_int_op(tor_log2(3),OP_EQ, 1);
  1330. tt_int_op(tor_log2(4),OP_EQ, 2);
  1331. tt_int_op(tor_log2(5),OP_EQ, 2);
  1332. tt_int_op(tor_log2(U64_LITERAL(40000000000000000)),OP_EQ, 55);
  1333. tt_int_op(tor_log2(UINT64_MAX),OP_EQ, 63);
  1334. /* Test round_to_power_of_2 */
  1335. tt_u64_op(round_to_power_of_2(120), OP_EQ, 128);
  1336. tt_u64_op(round_to_power_of_2(128), OP_EQ, 128);
  1337. tt_u64_op(round_to_power_of_2(130), OP_EQ, 128);
  1338. tt_u64_op(round_to_power_of_2(U64_LITERAL(40000000000000000)), OP_EQ,
  1339. U64_LITERAL(1)<<55);
  1340. tt_u64_op(round_to_power_of_2(U64_LITERAL(0xffffffffffffffff)), OP_EQ,
  1341. U64_LITERAL(1)<<63);
  1342. tt_u64_op(round_to_power_of_2(0), OP_EQ, 1);
  1343. tt_u64_op(round_to_power_of_2(1), OP_EQ, 1);
  1344. tt_u64_op(round_to_power_of_2(2), OP_EQ, 2);
  1345. tt_u64_op(round_to_power_of_2(3), OP_EQ, 2);
  1346. tt_u64_op(round_to_power_of_2(4), OP_EQ, 4);
  1347. tt_u64_op(round_to_power_of_2(5), OP_EQ, 4);
  1348. tt_u64_op(round_to_power_of_2(6), OP_EQ, 4);
  1349. tt_u64_op(round_to_power_of_2(7), OP_EQ, 8);
  1350. done:
  1351. ;
  1352. }
  1353. /** mutex for thread test to stop the threads hitting data at the same time. */
  1354. static tor_mutex_t *thread_test_mutex_ = NULL;
  1355. /** mutexes for the thread test to make sure that the threads have to
  1356. * interleave somewhat. */
  1357. static tor_mutex_t *thread_test_start1_ = NULL,
  1358. *thread_test_start2_ = NULL;
  1359. /** Shared strmap for the thread test. */
  1360. static strmap_t *thread_test_strmap_ = NULL;
  1361. /** The name of thread1 for the thread test */
  1362. static char *thread1_name_ = NULL;
  1363. /** The name of thread2 for the thread test */
  1364. static char *thread2_name_ = NULL;
  1365. static void thread_test_func_(void* _s) ATTR_NORETURN;
  1366. /** How many iterations have the threads in the unit test run? */
  1367. static int t1_count = 0, t2_count = 0;
  1368. /** Helper function for threading unit tests: This function runs in a
  1369. * subthread. It grabs its own mutex (start1 or start2) to make sure that it
  1370. * should start, then it repeatedly alters _test_thread_strmap protected by
  1371. * thread_test_mutex_. */
  1372. static void
  1373. thread_test_func_(void* _s)
  1374. {
  1375. char *s = _s;
  1376. int i, *count;
  1377. tor_mutex_t *m;
  1378. char buf[64];
  1379. char **cp;
  1380. if (!strcmp(s, "thread 1")) {
  1381. m = thread_test_start1_;
  1382. cp = &thread1_name_;
  1383. count = &t1_count;
  1384. } else {
  1385. m = thread_test_start2_;
  1386. cp = &thread2_name_;
  1387. count = &t2_count;
  1388. }
  1389. tor_snprintf(buf, sizeof(buf), "%lu", tor_get_thread_id());
  1390. *cp = tor_strdup(buf);
  1391. tor_mutex_acquire(m);
  1392. for (i=0; i<10000; ++i) {
  1393. tor_mutex_acquire(thread_test_mutex_);
  1394. strmap_set(thread_test_strmap_, "last to run", *cp);
  1395. ++*count;
  1396. tor_mutex_release(thread_test_mutex_);
  1397. }
  1398. tor_mutex_acquire(thread_test_mutex_);
  1399. strmap_set(thread_test_strmap_, s, *cp);
  1400. tor_mutex_release(thread_test_mutex_);
  1401. tor_mutex_release(m);
  1402. spawn_exit();
  1403. }
  1404. /** Run unit tests for threading logic. */
  1405. static void
  1406. test_util_threads(void *arg)
  1407. {
  1408. char *s1 = NULL, *s2 = NULL;
  1409. int done = 0, timedout = 0;
  1410. time_t started;
  1411. #ifndef _WIN32
  1412. struct timeval tv;
  1413. tv.tv_sec=0;
  1414. tv.tv_usec=100*1000;
  1415. #endif
  1416. (void)arg;
  1417. thread_test_mutex_ = tor_mutex_new();
  1418. thread_test_start1_ = tor_mutex_new();
  1419. thread_test_start2_ = tor_mutex_new();
  1420. thread_test_strmap_ = strmap_new();
  1421. s1 = tor_strdup("thread 1");
  1422. s2 = tor_strdup("thread 2");
  1423. tor_mutex_acquire(thread_test_start1_);
  1424. tor_mutex_acquire(thread_test_start2_);
  1425. spawn_func(thread_test_func_, s1);
  1426. spawn_func(thread_test_func_, s2);
  1427. tor_mutex_release(thread_test_start2_);
  1428. tor_mutex_release(thread_test_start1_);
  1429. started = time(NULL);
  1430. while (!done) {
  1431. tor_mutex_acquire(thread_test_mutex_);
  1432. strmap_assert_ok(thread_test_strmap_);
  1433. if (strmap_get(thread_test_strmap_, "thread 1") &&
  1434. strmap_get(thread_test_strmap_, "thread 2")) {
  1435. done = 1;
  1436. } else if (time(NULL) > started + 150) {
  1437. timedout = done = 1;
  1438. }
  1439. tor_mutex_release(thread_test_mutex_);
  1440. #ifndef _WIN32
  1441. /* Prevent the main thread from starving the worker threads. */
  1442. select(0, NULL, NULL, NULL, &tv);
  1443. #endif
  1444. }
  1445. tor_mutex_acquire(thread_test_start1_);
  1446. tor_mutex_release(thread_test_start1_);
  1447. tor_mutex_acquire(thread_test_start2_);
  1448. tor_mutex_release(thread_test_start2_);
  1449. tor_mutex_free(thread_test_mutex_);
  1450. if (timedout) {
  1451. printf("\nTimed out: %d %d", t1_count, t2_count);
  1452. tt_assert(strmap_get(thread_test_strmap_, "thread 1"));
  1453. tt_assert(strmap_get(thread_test_strmap_, "thread 2"));
  1454. tt_assert(!timedout);
  1455. }
  1456. /* different thread IDs. */
  1457. tt_assert(strcmp(strmap_get(thread_test_strmap_, "thread 1"),
  1458. strmap_get(thread_test_strmap_, "thread 2")));
  1459. tt_assert(!strcmp(strmap_get(thread_test_strmap_, "thread 1"),
  1460. strmap_get(thread_test_strmap_, "last to run")) ||
  1461. !strcmp(strmap_get(thread_test_strmap_, "thread 2"),
  1462. strmap_get(thread_test_strmap_, "last to run")));
  1463. done:
  1464. tor_free(s1);
  1465. tor_free(s2);
  1466. tor_free(thread1_name_);
  1467. tor_free(thread2_name_);
  1468. if (thread_test_strmap_)
  1469. strmap_free(thread_test_strmap_, NULL);
  1470. if (thread_test_start1_)
  1471. tor_mutex_free(thread_test_start1_);
  1472. if (thread_test_start2_)
  1473. tor_mutex_free(thread_test_start2_);
  1474. }
  1475. /** Run unit tests for compression functions */
  1476. static void
  1477. test_util_gzip(void *arg)
  1478. {
  1479. char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2;
  1480. const char *ccp2;
  1481. size_t len1, len2;
  1482. tor_zlib_state_t *state = NULL;
  1483. (void)arg;
  1484. buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
  1485. tt_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
  1486. if (is_gzip_supported()) {
  1487. tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  1488. GZIP_METHOD));
  1489. tt_assert(buf2);
  1490. tt_assert(len1 < strlen(buf1));
  1491. tt_assert(detect_compression_method(buf2, len1) == GZIP_METHOD);
  1492. tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
  1493. GZIP_METHOD, 1, LOG_INFO));
  1494. tt_assert(buf3);
  1495. tt_int_op(strlen(buf1) + 1,OP_EQ, len2);
  1496. tt_str_op(buf1,OP_EQ, buf3);
  1497. tor_free(buf2);
  1498. tor_free(buf3);
  1499. }
  1500. tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  1501. ZLIB_METHOD));
  1502. tt_assert(buf2);
  1503. tt_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD);
  1504. tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
  1505. ZLIB_METHOD, 1, LOG_INFO));
  1506. tt_assert(buf3);
  1507. tt_int_op(strlen(buf1) + 1,OP_EQ, len2);
  1508. tt_str_op(buf1,OP_EQ, buf3);
  1509. /* Check whether we can uncompress concatenated, compressed strings. */
  1510. tor_free(buf3);
  1511. buf2 = tor_reallocarray(buf2, len1, 2);
  1512. memcpy(buf2+len1, buf2, len1);
  1513. tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2,
  1514. ZLIB_METHOD, 1, LOG_INFO));
  1515. tt_int_op((strlen(buf1)+1)*2,OP_EQ, len2);
  1516. tt_mem_op(buf3,OP_EQ,
  1517. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
  1518. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
  1519. (strlen(buf1)+1)*2);
  1520. tor_free(buf1);
  1521. tor_free(buf2);
  1522. tor_free(buf3);
  1523. /* Check whether we can uncompress partial strings. */
  1524. buf1 =
  1525. tor_strdup("String with low redundancy that won't be compressed much.");
  1526. tt_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  1527. ZLIB_METHOD));
  1528. tt_assert(len1>16);
  1529. /* when we allow an incomplete string, we should succeed.*/
  1530. tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
  1531. ZLIB_METHOD, 0, LOG_INFO));
  1532. tt_assert(len2 > 5);
  1533. buf3[len2]='\0';
  1534. tt_assert(!strcmpstart(buf1, buf3));
  1535. /* when we demand a complete string, this must fail. */
  1536. tor_free(buf3);
  1537. tt_assert(tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
  1538. ZLIB_METHOD, 1, LOG_INFO));
  1539. tt_assert(!buf3);
  1540. /* Now, try streaming compression. */
  1541. tor_free(buf1);
  1542. tor_free(buf2);
  1543. tor_free(buf3);
  1544. state = tor_zlib_new(1, ZLIB_METHOD, HIGH_COMPRESSION);
  1545. tt_assert(state);
  1546. cp1 = buf1 = tor_malloc(1024);
  1547. len1 = 1024;
  1548. ccp2 = "ABCDEFGHIJABCDEFGHIJ";
  1549. len2 = 21;
  1550. tt_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0)
  1551. == TOR_ZLIB_OK);
  1552. tt_int_op(0,OP_EQ, len2); /* Make sure we compressed it all. */
  1553. tt_assert(cp1 > buf1);
  1554. len2 = 0;
  1555. cp2 = cp1;
  1556. tt_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1)
  1557. == TOR_ZLIB_DONE);
  1558. tt_int_op(0,OP_EQ, len2);
  1559. tt_assert(cp1 > cp2); /* Make sure we really added something. */
  1560. tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf1, 1024-len1,
  1561. ZLIB_METHOD, 1, LOG_WARN));
  1562. /* Make sure it compressed right. */
  1563. tt_str_op(buf3, OP_EQ, "ABCDEFGHIJABCDEFGHIJ");
  1564. tt_int_op(21,OP_EQ, len2);
  1565. done:
  1566. if (state)
  1567. tor_zlib_free(state);
  1568. tor_free(buf2);
  1569. tor_free(buf3);
  1570. tor_free(buf1);
  1571. }
  1572. /** Run unit tests for mmap() wrapper functionality. */
  1573. static void
  1574. test_util_mmap(void *arg)
  1575. {
  1576. char *fname1 = tor_strdup(get_fname("mapped_1"));
  1577. char *fname2 = tor_strdup(get_fname("mapped_2"));
  1578. char *fname3 = tor_strdup(get_fname("mapped_3"));
  1579. const size_t buflen = 17000;
  1580. char *buf = tor_malloc(17000);
  1581. tor_mmap_t *mapping = NULL;
  1582. (void)arg;
  1583. crypto_rand(buf, buflen);
  1584. mapping = tor_mmap_file(fname1);
  1585. tt_assert(! mapping);
  1586. write_str_to_file(fname1, "Short file.", 1);
  1587. mapping = tor_mmap_file(fname1);
  1588. tt_assert(mapping);
  1589. tt_int_op(mapping->size,OP_EQ, strlen("Short file."));
  1590. tt_str_op(mapping->data,OP_EQ, "Short file.");
  1591. #ifdef _WIN32
  1592. tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
  1593. mapping = NULL;
  1594. tt_assert(unlink(fname1) == 0);
  1595. #else
  1596. /* make sure we can unlink. */
  1597. tt_assert(unlink(fname1) == 0);
  1598. tt_str_op(mapping->data,OP_EQ, "Short file.");
  1599. tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
  1600. mapping = NULL;
  1601. #endif
  1602. /* Now a zero-length file. */
  1603. write_str_to_file(fname1, "", 1);
  1604. mapping = tor_mmap_file(fname1);
  1605. tt_ptr_op(mapping,OP_EQ, NULL);
  1606. tt_int_op(ERANGE,OP_EQ, errno);
  1607. unlink(fname1);
  1608. /* Make sure that we fail to map a no-longer-existent file. */
  1609. mapping = tor_mmap_file(fname1);
  1610. tt_assert(! mapping);
  1611. /* Now try a big file that stretches across a few pages and isn't aligned */
  1612. write_bytes_to_file(fname2, buf, buflen, 1);
  1613. mapping = tor_mmap_file(fname2);
  1614. tt_assert(mapping);
  1615. tt_int_op(mapping->size,OP_EQ, buflen);
  1616. tt_mem_op(mapping->data,OP_EQ, buf, buflen);
  1617. tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
  1618. mapping = NULL;
  1619. /* Now try a big aligned file. */
  1620. write_bytes_to_file(fname3, buf, 16384, 1);
  1621. mapping = tor_mmap_file(fname3);
  1622. tt_assert(mapping);
  1623. tt_int_op(mapping->size,OP_EQ, 16384);
  1624. tt_mem_op(mapping->data,OP_EQ, buf, 16384);
  1625. tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
  1626. mapping = NULL;
  1627. done:
  1628. unlink(fname1);
  1629. unlink(fname2);
  1630. unlink(fname3);
  1631. tor_free(fname1);
  1632. tor_free(fname2);
  1633. tor_free(fname3);
  1634. tor_free(buf);
  1635. tor_munmap_file(mapping);
  1636. }
  1637. /** Run unit tests for escaping/unescaping data for use by controllers. */
  1638. static void
  1639. test_util_control_formats(void *arg)
  1640. {
  1641. char *out = NULL;
  1642. const char *inp =
  1643. "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
  1644. size_t sz;
  1645. (void)arg;
  1646. sz = read_escaped_data(inp, strlen(inp), &out);
  1647. tt_str_op(out,OP_EQ,
  1648. ".This is a test\nof the emergency \n.system.\n\rZ.\n");
  1649. tt_int_op(sz,OP_EQ, strlen(out));
  1650. done:
  1651. tor_free(out);
  1652. }
  1653. #define test_feq(value1,value2) do { \
  1654. double v1 = (value1), v2=(value2); \
  1655. double tf_diff = v1-v2; \
  1656. double tf_tolerance = ((v1+v2)/2.0)/1e8; \
  1657. if (tf_diff<0) tf_diff=-tf_diff; \
  1658. if (tf_tolerance<0) tf_tolerance=-tf_tolerance; \
  1659. if (tf_diff<tf_tolerance) { \
  1660. TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2)); \
  1661. } else { \
  1662. TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
  1663. } \
  1664. } while (0)
  1665. static void
  1666. test_util_sscanf(void *arg)
  1667. {
  1668. unsigned u1, u2, u3;
  1669. unsigned long ulng;
  1670. char s1[20], s2[10], s3[10], ch;
  1671. int r;
  1672. long lng1,lng2;
  1673. int int1, int2;
  1674. double d1,d2,d3,d4;
  1675. /* Simple tests (malformed patterns, literal matching, ...) */
  1676. (void)arg;
  1677. tt_int_op(-1,OP_EQ, tor_sscanf("123", "%i", &r)); /* %i is not supported */
  1678. tt_int_op(-1,OP_EQ,
  1679. tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */
  1680. tt_int_op(-1,OP_EQ, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */
  1681. tt_int_op(-1,OP_EQ, tor_sscanf("prettylongstring", "%999999s", s1));
  1682. #if 0
  1683. /* GCC thinks these two are illegal. */
  1684. test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1));
  1685. test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL));
  1686. #endif
  1687. /* No '%'-strings: always "success" */
  1688. tt_int_op(0,OP_EQ, tor_sscanf("hello world", "hello world"));
  1689. tt_int_op(0,OP_EQ, tor_sscanf("hello world", "good bye"));
  1690. /* Excess data */
  1691. tt_int_op(0,OP_EQ,
  1692. tor_sscanf("hello 3", "%u", &u1)); /* have to match the start */
  1693. tt_int_op(0,OP_EQ, tor_sscanf(" 3 hello", "%u", &u1));
  1694. tt_int_op(0,OP_EQ,
  1695. tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */
  1696. tt_int_op(1,OP_EQ,
  1697. tor_sscanf("3 hello", "%u", &u1)); /* but trailing is alright */
  1698. /* Numbers (ie. %u) */
  1699. tt_int_op(0,OP_EQ,
  1700. tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */
  1701. tt_int_op(1,OP_EQ, tor_sscanf("12345", "%u", &u1));
  1702. tt_int_op(12345u,OP_EQ, u1);
  1703. tt_int_op(1,OP_EQ, tor_sscanf("12346 ", "%u", &u1));
  1704. tt_int_op(12346u,OP_EQ, u1);
  1705. tt_int_op(0,OP_EQ, tor_sscanf(" 12347", "%u", &u1));
  1706. tt_int_op(1,OP_EQ, tor_sscanf(" 12348", " %u", &u1));
  1707. tt_int_op(12348u,OP_EQ, u1);
  1708. tt_int_op(1,OP_EQ, tor_sscanf("0", "%u", &u1));
  1709. tt_int_op(0u,OP_EQ, u1);
  1710. tt_int_op(1,OP_EQ, tor_sscanf("0000", "%u", &u2));
  1711. tt_int_op(0u,OP_EQ, u2);
  1712. tt_int_op(0,OP_EQ, tor_sscanf("", "%u", &u1)); /* absent number */
  1713. tt_int_op(0,OP_EQ, tor_sscanf("A", "%u", &u1)); /* bogus number */
  1714. tt_int_op(0,OP_EQ, tor_sscanf("-1", "%u", &u1)); /* negative number */
  1715. /* Numbers with size (eg. %2u) */
  1716. tt_int_op(0,OP_EQ, tor_sscanf("-1", "%2u", &u1));
  1717. tt_int_op(2,OP_EQ, tor_sscanf("123456", "%2u%u", &u1, &u2));
  1718. tt_int_op(12u,OP_EQ, u1);
  1719. tt_int_op(3456u,OP_EQ, u2);
  1720. tt_int_op(1,OP_EQ, tor_sscanf("123456", "%8u", &u1));
  1721. tt_int_op(123456u,OP_EQ, u1);
  1722. tt_int_op(1,OP_EQ, tor_sscanf("123457 ", "%8u", &u1));
  1723. tt_int_op(123457u,OP_EQ, u1);
  1724. tt_int_op(0,OP_EQ, tor_sscanf(" 123456", "%8u", &u1));
  1725. tt_int_op(3,OP_EQ, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3));
  1726. tt_int_op(12u,OP_EQ, u1);
  1727. tt_int_op(3u,OP_EQ, u2);
  1728. tt_int_op(456u,OP_EQ, u3);
  1729. tt_int_op(3,OP_EQ,
  1730. tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */
  1731. tt_int_op(67u,OP_EQ, u1);
  1732. tt_int_op(8u,OP_EQ, u2);
  1733. tt_int_op(99u,OP_EQ, u3);
  1734. /* %u does not match space.*/
  1735. tt_int_op(2,OP_EQ, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3));
  1736. tt_int_op(12u,OP_EQ, u1);
  1737. tt_int_op(3u,OP_EQ, u2);
  1738. /* %u does not match negative numbers. */
  1739. tt_int_op(2,OP_EQ, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3));
  1740. tt_int_op(67u,OP_EQ, u1);
  1741. tt_int_op(8u,OP_EQ, u2);
  1742. /* Arbitrary amounts of 0-padding are okay */
  1743. tt_int_op(3,OP_EQ, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
  1744. &u1, &u2, &u3));
  1745. tt_int_op(12u,OP_EQ, u1);
  1746. tt_int_op(3u,OP_EQ, u2);
  1747. tt_int_op(99u,OP_EQ, u3);
  1748. /* Hex (ie. %x) */
  1749. tt_int_op(3,OP_EQ,
  1750. tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3));
  1751. tt_int_op(0x1234,OP_EQ, u1);
  1752. tt_int_op(0x2ABCDEF,OP_EQ, u2);
  1753. tt_int_op(0xFF,OP_EQ, u3);
  1754. /* Width works on %x */
  1755. tt_int_op(3,OP_EQ, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3));
  1756. tt_int_op(0xf00d,OP_EQ, u1);
  1757. tt_int_op(0xcafe,OP_EQ, u2);
  1758. tt_int_op(444,OP_EQ, u3);
  1759. /* Literal '%' (ie. '%%') */
  1760. tt_int_op(1,OP_EQ, tor_sscanf("99% fresh", "%3u%% fresh", &u1));
  1761. tt_int_op(99,OP_EQ, u1);
  1762. tt_int_op(0,OP_EQ, tor_sscanf("99 fresh", "%% %3u %s", &u1, s1));
  1763. tt_int_op(1,OP_EQ, tor_sscanf("99 fresh", "%3u%% %s", &u1, s1));
  1764. tt_int_op(2,OP_EQ, tor_sscanf("99 fresh", "%3u %5s %%", &u1, s1));
  1765. tt_int_op(99,OP_EQ, u1);
  1766. tt_str_op(s1,OP_EQ, "fresh");
  1767. tt_int_op(1,OP_EQ, tor_sscanf("% boo", "%% %3s", s1));
  1768. tt_str_op("boo",OP_EQ, s1);
  1769. /* Strings (ie. %s) */
  1770. tt_int_op(2,OP_EQ, tor_sscanf("hello", "%3s%7s", s1, s2));
  1771. tt_str_op(s1,OP_EQ, "hel");
  1772. tt_str_op(s2,OP_EQ, "lo");
  1773. tt_int_op(2,OP_EQ, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */
  1774. tt_str_op(s3,OP_EQ, "WD");
  1775. tt_int_op(40,OP_EQ, u1);
  1776. tt_int_op(2,OP_EQ, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */
  1777. tt_str_op(s3,OP_EQ, "WD4");
  1778. tt_int_op(0,OP_EQ, u1);
  1779. tt_int_op(2,OP_EQ, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */
  1780. tt_int_op(76,OP_EQ, u1);
  1781. tt_str_op(s1,OP_EQ, "trombones");
  1782. tt_int_op(1,OP_EQ, tor_sscanf("prettylongstring", "%999s", s1));
  1783. tt_str_op(s1,OP_EQ, "prettylongstring");
  1784. /* %s doesn't eat spaces */
  1785. tt_int_op(2,OP_EQ, tor_sscanf("hello world", "%9s %9s", s1, s2));
  1786. tt_str_op(s1,OP_EQ, "hello");
  1787. tt_str_op(s2,OP_EQ, "world");
  1788. tt_int_op(2,OP_EQ, tor_sscanf("bye world?", "%9s %9s", s1, s2));
  1789. tt_str_op(s1,OP_EQ, "bye");
  1790. tt_str_op(s2,OP_EQ, "");
  1791. tt_int_op(3,OP_EQ,
  1792. tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */
  1793. tt_str_op(s1,OP_EQ, "hi");
  1794. tt_str_op(s2,OP_EQ, "");
  1795. tt_str_op(s3,OP_EQ, "");
  1796. tt_int_op(3,OP_EQ, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
  1797. tt_int_op(4,OP_EQ,
  1798. tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
  1799. tt_int_op(' ',OP_EQ, ch);
  1800. r = tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1, &lng1, &int2);
  1801. tt_int_op(r,OP_EQ, 3);
  1802. tt_int_op(int1,OP_EQ, 12345);
  1803. tt_int_op(lng1,OP_EQ, -67890);
  1804. tt_int_op(int2,OP_EQ, -1);
  1805. #if SIZEOF_INT == 4
  1806. /* %u */
  1807. /* UINT32_MAX should work */
  1808. tt_int_op(1,OP_EQ, tor_sscanf("4294967295", "%u", &u1));
  1809. tt_int_op(4294967295U,OP_EQ, u1);
  1810. /* But UINT32_MAX + 1 shouldn't work */
  1811. tt_int_op(0,OP_EQ, tor_sscanf("4294967296", "%u", &u1));
  1812. /* but parsing only 9... */
  1813. tt_int_op(1,OP_EQ, tor_sscanf("4294967296", "%9u", &u1));
  1814. tt_int_op(429496729U,OP_EQ, u1);
  1815. /* %x */
  1816. /* UINT32_MAX should work */
  1817. tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFF", "%x", &u1));
  1818. tt_int_op(0xFFFFFFFF,OP_EQ, u1);
  1819. /* But UINT32_MAX + 1 shouldn't work */
  1820. tt_int_op(0,OP_EQ, tor_sscanf("100000000", "%x", &u1));
  1821. /* %d */
  1822. /* INT32_MIN and INT32_MAX should work */
  1823. r = tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1, &int2);
  1824. tt_int_op(r,OP_EQ, 2);
  1825. tt_int_op(int1,OP_EQ, -2147483647 - 1);
  1826. tt_int_op(int2,OP_EQ, 2147483647);
  1827. /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
  1828. r = tor_sscanf("-2147483649.", "%d.", &int1);
  1829. tt_int_op(r,OP_EQ, 0);
  1830. r = tor_sscanf("2147483648.", "%d.", &int1);
  1831. tt_int_op(r,OP_EQ, 0);
  1832. /* and the first failure stops further processing */
  1833. r = tor_sscanf("-2147483648. 2147483648.",
  1834. "%d. %d.", &int1, &int2);
  1835. tt_int_op(r,OP_EQ, 1);
  1836. r = tor_sscanf("-2147483649. 2147483647.",
  1837. "%d. %d.", &int1, &int2);
  1838. tt_int_op(r,OP_EQ, 0);
  1839. r = tor_sscanf("2147483648. -2147483649.",
  1840. "%d. %d.", &int1, &int2);
  1841. tt_int_op(r,OP_EQ, 0);
  1842. #elif SIZEOF_INT == 8
  1843. /* %u */
  1844. /* UINT64_MAX should work */
  1845. tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551615", "%u", &u1));
  1846. tt_int_op(18446744073709551615U,OP_EQ, u1);
  1847. /* But UINT64_MAX + 1 shouldn't work */
  1848. tt_int_op(0,OP_EQ, tor_sscanf("18446744073709551616", "%u", &u1));
  1849. /* but parsing only 19... */
  1850. tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551616", "%19u", &u1));
  1851. tt_int_op(1844674407370955161U,OP_EQ, u1);
  1852. /* %x */
  1853. /* UINT64_MAX should work */
  1854. tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1));
  1855. tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ, u1);
  1856. /* But UINT64_MAX + 1 shouldn't work */
  1857. tt_int_op(0,OP_EQ, tor_sscanf("10000000000000000", "%x", &u1));
  1858. /* %d */
  1859. /* INT64_MIN and INT64_MAX should work */
  1860. r = tor_sscanf("-9223372036854775808. 9223372036854775807.",
  1861. "%d. %d.", &int1, &int2);
  1862. tt_int_op(r,OP_EQ, 2);
  1863. tt_int_op(int1,OP_EQ, -9223372036854775807 - 1);
  1864. tt_int_op(int2,OP_EQ, 9223372036854775807);
  1865. /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
  1866. r = tor_sscanf("-9223372036854775809.", "%d.", &int1);
  1867. tt_int_op(r,OP_EQ, 0);
  1868. r = tor_sscanf("9223372036854775808.", "%d.", &int1);
  1869. tt_int_op(r,OP_EQ, 0);
  1870. /* and the first failure stops further processing */
  1871. r = tor_sscanf("-9223372036854775808. 9223372036854775808.",
  1872. "%d. %d.", &int1, &int2);
  1873. tt_int_op(r,OP_EQ, 1);
  1874. r = tor_sscanf("-9223372036854775809. 9223372036854775807.",
  1875. "%d. %d.", &int1, &int2);
  1876. tt_int_op(r,OP_EQ, 0);
  1877. r = tor_sscanf("9223372036854775808. -9223372036854775809.",
  1878. "%d. %d.", &int1, &int2);
  1879. tt_int_op(r,OP_EQ, 0);
  1880. #endif
  1881. #if SIZEOF_LONG == 4
  1882. /* %lu */
  1883. /* UINT32_MAX should work */
  1884. tt_int_op(1,OP_EQ, tor_sscanf("4294967295", "%lu", &ulng));
  1885. tt_int_op(4294967295UL,OP_EQ, ulng);
  1886. /* But UINT32_MAX + 1 shouldn't work */
  1887. tt_int_op(0,OP_EQ, tor_sscanf("4294967296", "%lu", &ulng));
  1888. /* but parsing only 9... */
  1889. tt_int_op(1,OP_EQ, tor_sscanf("4294967296", "%9lu", &ulng));
  1890. tt_int_op(429496729UL,OP_EQ, ulng);
  1891. /* %lx */
  1892. /* UINT32_MAX should work */
  1893. tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFF", "%lx", &ulng));
  1894. tt_int_op(0xFFFFFFFFUL,OP_EQ, ulng);
  1895. /* But UINT32_MAX + 1 shouldn't work */
  1896. tt_int_op(0,OP_EQ, tor_sscanf("100000000", "%lx", &ulng));
  1897. /* %ld */
  1898. /* INT32_MIN and INT32_MAX should work */
  1899. r = tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1, &lng2);
  1900. tt_int_op(r,OP_EQ, 2);
  1901. tt_int_op(lng1,OP_EQ, -2147483647L - 1L);
  1902. tt_int_op(lng2,OP_EQ, 2147483647L);
  1903. /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
  1904. r = tor_sscanf("-2147483649.", "%ld.", &lng1);
  1905. tt_int_op(r,OP_EQ, 0);
  1906. r = tor_sscanf("2147483648.", "%ld.", &lng1);
  1907. tt_int_op(r,OP_EQ, 0);
  1908. /* and the first failure stops further processing */
  1909. r = tor_sscanf("-2147483648. 2147483648.",
  1910. "%ld. %ld.", &lng1, &lng2);
  1911. tt_int_op(r,OP_EQ, 1);
  1912. r = tor_sscanf("-2147483649. 2147483647.",
  1913. "%ld. %ld.", &lng1, &lng2);
  1914. tt_int_op(r,OP_EQ, 0);
  1915. r = tor_sscanf("2147483648. -2147483649.",
  1916. "%ld. %ld.", &lng1, &lng2);
  1917. tt_int_op(r,OP_EQ, 0);
  1918. #elif SIZEOF_LONG == 8
  1919. /* %lu */
  1920. /* UINT64_MAX should work */
  1921. tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551615", "%lu", &ulng));
  1922. tt_int_op(18446744073709551615UL,OP_EQ, ulng);
  1923. /* But UINT64_MAX + 1 shouldn't work */
  1924. tt_int_op(0,OP_EQ, tor_sscanf("18446744073709551616", "%lu", &ulng));
  1925. /* but parsing only 19... */
  1926. tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551616", "%19lu", &ulng));
  1927. tt_int_op(1844674407370955161UL,OP_EQ, ulng);
  1928. /* %lx */
  1929. /* UINT64_MAX should work */
  1930. tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng));
  1931. tt_int_op(0xFFFFFFFFFFFFFFFFUL,OP_EQ, ulng);
  1932. /* But UINT64_MAX + 1 shouldn't work */
  1933. tt_int_op(0,OP_EQ, tor_sscanf("10000000000000000", "%lx", &ulng));
  1934. /* %ld */
  1935. /* INT64_MIN and INT64_MAX should work */
  1936. r = tor_sscanf("-9223372036854775808. 9223372036854775807.",
  1937. "%ld. %ld.", &lng1, &lng2);
  1938. tt_int_op(r,OP_EQ, 2);
  1939. tt_int_op(lng1,OP_EQ, -9223372036854775807L - 1L);
  1940. tt_int_op(lng2,OP_EQ, 9223372036854775807L);
  1941. /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
  1942. r = tor_sscanf("-9223372036854775809.", "%ld.", &lng1);
  1943. tt_int_op(r,OP_EQ, 0);
  1944. r = tor_sscanf("9223372036854775808.", "%ld.", &lng1);
  1945. tt_int_op(r,OP_EQ, 0);
  1946. /* and the first failure stops further processing */
  1947. r = tor_sscanf("-9223372036854775808. 9223372036854775808.",
  1948. "%ld. %ld.", &lng1, &lng2);
  1949. tt_int_op(r,OP_EQ, 1);
  1950. r = tor_sscanf("-9223372036854775809. 9223372036854775807.",
  1951. "%ld. %ld.", &lng1, &lng2);
  1952. tt_int_op(r,OP_EQ, 0);
  1953. r = tor_sscanf("9223372036854775808. -9223372036854775809.",
  1954. "%ld. %ld.", &lng1, &lng2);
  1955. tt_int_op(r,OP_EQ, 0);
  1956. #endif
  1957. r = tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
  1958. "%lf %lf %lf %lf", &d1,&d2,&d3,&d4);
  1959. tt_int_op(r,OP_EQ, 4);
  1960. test_feq(d1, 123.456);
  1961. test_feq(d2, .000007);
  1962. test_feq(d3, -900123123.2000787);
  1963. test_feq(d4, 3.2);
  1964. done:
  1965. ;
  1966. }
  1967. #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
  1968. #define tt_ci_char_op(a,op,b) tt_char_op(tolower(a),op,tolower(b))
  1969. #ifndef HAVE_STRNLEN
  1970. static size_t
  1971. strnlen(const char *s, size_t len)
  1972. {
  1973. const char *p = memchr(s, 0, len);
  1974. if (!p)
  1975. return len;
  1976. return p - s;
  1977. }
  1978. #endif
  1979. static void
  1980. test_util_format_time_interval(void *arg)
  1981. {
  1982. /* use the same sized buffer and integers as tor uses */
  1983. #define DBUF_SIZE 64
  1984. char dbuf[DBUF_SIZE];
  1985. #define T_ "%ld"
  1986. long sec, min, hour, day;
  1987. /* we don't care about the exact spelling of the
  1988. * second(s), minute(s), hour(s), day(s) labels */
  1989. #define LABEL_SIZE 21
  1990. #define L_ "%20s"
  1991. char label_s[LABEL_SIZE];
  1992. char label_m[LABEL_SIZE];
  1993. char label_h[LABEL_SIZE];
  1994. char label_d[LABEL_SIZE];
  1995. #define TL_ T_ " " L_
  1996. int r;
  1997. (void)arg;
  1998. /* In these tests, we're not picky about
  1999. * spelling or abbreviations */
  2000. /* seconds: 0, 1, 9, 10, 59 */
  2001. /* ignore exact spelling of "second(s)"*/
  2002. format_time_interval(dbuf, sizeof(dbuf), 0);
  2003. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2004. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2005. tt_int_op(r,OP_EQ, 2);
  2006. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2007. tt_int_op(sec,OP_EQ, 0);
  2008. format_time_interval(dbuf, sizeof(dbuf), 1);
  2009. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2010. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2011. tt_int_op(r,OP_EQ, 2);
  2012. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2013. tt_int_op(sec,OP_EQ, 1);
  2014. format_time_interval(dbuf, sizeof(dbuf), 10);
  2015. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2016. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2017. tt_int_op(r,OP_EQ, 2);
  2018. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2019. tt_int_op(sec,OP_EQ, 10);
  2020. format_time_interval(dbuf, sizeof(dbuf), 59);
  2021. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2022. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2023. tt_int_op(r,OP_EQ, 2);
  2024. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2025. tt_int_op(sec,OP_EQ, 59);
  2026. /* negative seconds are reported as their absolute value */
  2027. format_time_interval(dbuf, sizeof(dbuf), -4);
  2028. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2029. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2030. tt_int_op(r,OP_EQ, 2);
  2031. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2032. tt_int_op(sec,OP_EQ, 4);
  2033. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2034. format_time_interval(dbuf, sizeof(dbuf), -32);
  2035. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2036. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2037. tt_int_op(r,OP_EQ, 2);
  2038. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2039. tt_int_op(sec,OP_EQ, 32);
  2040. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2041. /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
  2042. /* ignore trailing "0 second(s)", if present */
  2043. format_time_interval(dbuf, sizeof(dbuf), 60);
  2044. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2045. r = tor_sscanf(dbuf, TL_, &min, label_m);
  2046. tt_int_op(r,OP_EQ, 2);
  2047. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2048. tt_int_op(min,OP_EQ, 1);
  2049. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2050. /* ignore exact spelling of "minute(s)," and "second(s)" */
  2051. format_time_interval(dbuf, sizeof(dbuf), 60 + 1);
  2052. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2053. r = tor_sscanf(dbuf, TL_ " " TL_,
  2054. &min, label_m, &sec, label_s);
  2055. tt_int_op(r,OP_EQ, 4);
  2056. tt_int_op(min,OP_EQ, 1);
  2057. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2058. tt_int_op(sec,OP_EQ, 1);
  2059. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2060. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2061. format_time_interval(dbuf, sizeof(dbuf), 60*2 - 1);
  2062. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2063. r = tor_sscanf(dbuf, TL_ " " TL_,
  2064. &min, label_m, &sec, label_s);
  2065. tt_int_op(r,OP_EQ, 4);
  2066. tt_int_op(min,OP_EQ, 1);
  2067. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2068. tt_int_op(sec,OP_EQ, 59);
  2069. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2070. /* ignore trailing "0 second(s)", if present */
  2071. format_time_interval(dbuf, sizeof(dbuf), 60*2);
  2072. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2073. r = tor_sscanf(dbuf, TL_, &min, label_m);
  2074. tt_int_op(r,OP_EQ, 2);
  2075. tt_int_op(min,OP_EQ, 2);
  2076. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2077. /* ignore exact spelling of "minute(s)," and "second(s)" */
  2078. format_time_interval(dbuf, sizeof(dbuf), 60*2 + 1);
  2079. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2080. r = tor_sscanf(dbuf, TL_ " " TL_,
  2081. &min, label_m, &sec, label_s);
  2082. tt_int_op(r,OP_EQ, 4);
  2083. tt_int_op(min,OP_EQ, 2);
  2084. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2085. tt_int_op(sec,OP_EQ, 1);
  2086. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2087. format_time_interval(dbuf, sizeof(dbuf), 60*60 - 1);
  2088. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2089. r = tor_sscanf(dbuf, TL_ " " TL_,
  2090. &min, label_m, &sec, label_s);
  2091. tt_int_op(r,OP_EQ, 4);
  2092. tt_int_op(min,OP_EQ, 59);
  2093. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2094. tt_int_op(sec,OP_EQ, 59);
  2095. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2096. /* negative minutes are reported as their absolute value */
  2097. /* ignore trailing "0 second(s)", if present */
  2098. format_time_interval(dbuf, sizeof(dbuf), -3*60);
  2099. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2100. r = tor_sscanf(dbuf, TL_, &min, label_m);
  2101. tt_int_op(r,OP_EQ, 2);
  2102. tt_int_op(min,OP_EQ, 3);
  2103. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2104. /* ignore exact spelling of "minute(s)," and "second(s)" */
  2105. format_time_interval(dbuf, sizeof(dbuf), -96);
  2106. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2107. r = tor_sscanf(dbuf, TL_ " " TL_,
  2108. &min, label_m, &sec, label_s);
  2109. tt_int_op(r,OP_EQ, 4);
  2110. tt_int_op(min,OP_EQ, 1);
  2111. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2112. tt_int_op(sec,OP_EQ, 36);
  2113. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2114. format_time_interval(dbuf, sizeof(dbuf), -2815);
  2115. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2116. r = tor_sscanf(dbuf, TL_ " " TL_,
  2117. &min, label_m, &sec, label_s);
  2118. tt_int_op(r,OP_EQ, 4);
  2119. tt_int_op(min,OP_EQ, 46);
  2120. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2121. tt_int_op(sec,OP_EQ, 55);
  2122. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2123. /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
  2124. /* always ignore trailing seconds, if present */
  2125. /* ignore trailing "0 minute(s)" etc., if present */
  2126. format_time_interval(dbuf, sizeof(dbuf), 60*60);
  2127. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2128. r = tor_sscanf(dbuf, TL_, &hour, label_h);
  2129. tt_int_op(r,OP_EQ, 2);
  2130. tt_int_op(hour,OP_EQ, 1);
  2131. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2132. format_time_interval(dbuf, sizeof(dbuf), 60*60 + 1);
  2133. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2134. r = tor_sscanf(dbuf, TL_, &hour, label_h);
  2135. tt_int_op(r,OP_EQ, 2);
  2136. tt_int_op(hour,OP_EQ, 1);
  2137. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2138. /* ignore exact spelling of "hour(s)," etc. */
  2139. format_time_interval(dbuf, sizeof(dbuf), 60*60 + 60);
  2140. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2141. r = tor_sscanf(dbuf, TL_ " " TL_,
  2142. &hour, label_h, &min, label_m);
  2143. tt_int_op(r,OP_EQ, 4);
  2144. tt_int_op(hour,OP_EQ, 1);
  2145. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2146. tt_int_op(min,OP_EQ, 1);
  2147. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2148. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 - 60);
  2149. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2150. r = tor_sscanf(dbuf, TL_ " " TL_,
  2151. &hour, label_h, &min, label_m);
  2152. tt_int_op(r,OP_EQ, 4);
  2153. tt_int_op(hour,OP_EQ, 23);
  2154. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2155. tt_int_op(min,OP_EQ, 59);
  2156. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2157. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 - 1);
  2158. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2159. r = tor_sscanf(dbuf, TL_ " " TL_,
  2160. &hour, label_h, &min, label_m);
  2161. tt_int_op(r,OP_EQ, 4);
  2162. tt_int_op(hour,OP_EQ, 23);
  2163. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2164. tt_int_op(min,OP_EQ, 59);
  2165. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2166. /* negative hours are reported as their absolute value */
  2167. /* ignore exact spelling of "hour(s)," etc., if present */
  2168. format_time_interval(dbuf, sizeof(dbuf), -2*60*60);
  2169. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2170. r = tor_sscanf(dbuf, TL_, &hour, label_h);
  2171. tt_int_op(r,OP_EQ, 2);
  2172. tt_int_op(hour,OP_EQ, 2);
  2173. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2174. format_time_interval(dbuf, sizeof(dbuf), -75804);
  2175. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2176. r = tor_sscanf(dbuf, TL_ " " TL_,
  2177. &hour, label_h, &min, label_m);
  2178. tt_int_op(r,OP_EQ, 4);
  2179. tt_int_op(hour,OP_EQ, 21);
  2180. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2181. tt_int_op(min,OP_EQ, 3);
  2182. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2183. /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
  2184. /* always ignore trailing seconds, if present */
  2185. /* ignore trailing "0 hours(s)" etc., if present */
  2186. format_time_interval(dbuf, sizeof(dbuf), 24*60*60);
  2187. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2188. r = tor_sscanf(dbuf, TL_, &day, label_d);
  2189. tt_int_op(r,OP_EQ, 2);
  2190. tt_int_op(day,OP_EQ, 1);
  2191. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2192. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 1);
  2193. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2194. r = tor_sscanf(dbuf, TL_, &day, label_d);
  2195. tt_int_op(r,OP_EQ, 2);
  2196. tt_int_op(day,OP_EQ, 1);
  2197. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2198. /* ignore exact spelling of "days(s)," etc. */
  2199. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 60);
  2200. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2201. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  2202. &day, label_d, &hour, label_h, &min, label_m);
  2203. if (r == -1) {
  2204. /* ignore 0 hours(s), if present */
  2205. r = tor_sscanf(dbuf, TL_ " " TL_,
  2206. &day, label_d, &min, label_m);
  2207. }
  2208. tt_assert(r == 4 || r == 6);
  2209. tt_int_op(day,OP_EQ, 1);
  2210. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2211. if (r == 6) {
  2212. tt_int_op(hour,OP_EQ, 0);
  2213. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2214. }
  2215. tt_int_op(min,OP_EQ, 1);
  2216. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2217. /* ignore trailing "0 minutes(s)" etc., if present */
  2218. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 60*60);
  2219. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2220. r = tor_sscanf(dbuf, TL_ " " TL_,
  2221. &day, label_d, &hour, label_h);
  2222. tt_int_op(r,OP_EQ, 4);
  2223. tt_int_op(day,OP_EQ, 1);
  2224. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2225. tt_int_op(hour,OP_EQ, 1);
  2226. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2227. /* negative days are reported as their absolute value */
  2228. format_time_interval(dbuf, sizeof(dbuf), -21936184);
  2229. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2230. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  2231. &day, label_d, &hour, label_h, &min, label_m);
  2232. tt_int_op(r,OP_EQ, 6);
  2233. tt_int_op(day,OP_EQ, 253);
  2234. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2235. tt_int_op(hour,OP_EQ, 21);
  2236. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2237. tt_int_op(min,OP_EQ, 23);
  2238. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2239. /* periods > 1 year are reported in days (warn?) */
  2240. /* ignore exact spelling of "days(s)," etc., if present */
  2241. format_time_interval(dbuf, sizeof(dbuf), 758635154);
  2242. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2243. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  2244. &day, label_d, &hour, label_h, &min, label_m);
  2245. tt_int_op(r,OP_EQ, 6);
  2246. tt_int_op(day,OP_EQ, 8780);
  2247. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2248. tt_int_op(hour,OP_EQ, 11);
  2249. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2250. tt_int_op(min,OP_EQ, 59);
  2251. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2252. /* negative periods > 1 year are reported in days (warn?) */
  2253. format_time_interval(dbuf, sizeof(dbuf), -1427014922);
  2254. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2255. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  2256. &day, label_d, &hour, label_h, &min, label_m);
  2257. tt_int_op(r,OP_EQ, 6);
  2258. tt_int_op(day,OP_EQ, 16516);
  2259. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2260. tt_int_op(hour,OP_EQ, 9);
  2261. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2262. tt_int_op(min,OP_EQ, 2);
  2263. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2264. #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
  2265. /* We can try INT32_MIN/MAX */
  2266. /* Always ignore second(s) */
  2267. /* INT32_MAX */
  2268. format_time_interval(dbuf, sizeof(dbuf), 2147483647);
  2269. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2270. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  2271. &day, label_d, &hour, label_h, &min, label_m);
  2272. tt_int_op(r,OP_EQ, 6);
  2273. tt_int_op(day,OP_EQ, 24855);
  2274. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2275. tt_int_op(hour,OP_EQ, 3);
  2276. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2277. tt_int_op(min,OP_EQ, 14);
  2278. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2279. /* and 7 seconds - ignored */
  2280. /* INT32_MIN: check that we get the absolute value of interval,
  2281. * which doesn't actually fit in int32_t.
  2282. * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
  2283. format_time_interval(dbuf, sizeof(dbuf), -2147483647L - 1L);
  2284. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2285. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  2286. &day, label_d, &hour, label_h, &min, label_m);
  2287. tt_int_op(r,OP_EQ, 6);
  2288. tt_int_op(day,OP_EQ, 24855);
  2289. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2290. tt_int_op(hour,OP_EQ, 3);
  2291. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2292. tt_int_op(min,OP_EQ, 14);
  2293. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2294. /* and 7 or 8 seconds - ignored */
  2295. #endif
  2296. #if SIZEOF_LONG == 8
  2297. /* We can try INT64_MIN/MAX */
  2298. /* Always ignore second(s) */
  2299. /* INT64_MAX */
  2300. format_time_interval(dbuf, sizeof(dbuf), 9223372036854775807L);
  2301. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2302. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  2303. &day, label_d, &hour, label_h, &min, label_m);
  2304. tt_int_op(r,OP_EQ, 6);
  2305. tt_int_op(day,OP_EQ, 106751991167300L);
  2306. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2307. tt_int_op(hour,OP_EQ, 15);
  2308. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2309. tt_int_op(min,OP_EQ, 30);
  2310. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2311. /* and 7 seconds - ignored */
  2312. /* INT64_MIN: check that we get the absolute value of interval,
  2313. * which doesn't actually fit in int64_t.
  2314. * We expect INT64_MAX */
  2315. format_time_interval(dbuf, sizeof(dbuf),
  2316. -9223372036854775807L - 1L);
  2317. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2318. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  2319. &day, label_d, &hour, label_h, &min, label_m);
  2320. tt_int_op(r,OP_EQ, 6);
  2321. tt_int_op(day,OP_EQ, 106751991167300L);
  2322. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  2323. tt_int_op(hour,OP_EQ, 15);
  2324. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2325. tt_int_op(min,OP_EQ, 30);
  2326. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2327. /* and 7 or 8 seconds - ignored */
  2328. #endif
  2329. done:
  2330. ;
  2331. }
  2332. #undef tt_char_op
  2333. #undef tt_ci_char_op
  2334. #undef DBUF_SIZE
  2335. #undef T_
  2336. #undef LABEL_SIZE
  2337. #undef L_
  2338. #undef TL_
  2339. static void
  2340. test_util_path_is_relative(void *arg)
  2341. {
  2342. /* OS-independent tests */
  2343. (void)arg;
  2344. tt_int_op(1,OP_EQ, path_is_relative(""));
  2345. tt_int_op(1,OP_EQ, path_is_relative("dir"));
  2346. tt_int_op(1,OP_EQ, path_is_relative("dir/"));
  2347. tt_int_op(1,OP_EQ, path_is_relative("./dir"));
  2348. tt_int_op(1,OP_EQ, path_is_relative("../dir"));
  2349. tt_int_op(0,OP_EQ, path_is_relative("/"));
  2350. tt_int_op(0,OP_EQ, path_is_relative("/dir"));
  2351. tt_int_op(0,OP_EQ, path_is_relative("/dir/"));
  2352. /* Windows */
  2353. #ifdef _WIN32
  2354. /* I don't have Windows so I can't test this, hence the "#ifdef
  2355. 0". These are tests that look useful, so please try to get them
  2356. running and uncomment if it all works as it should */
  2357. tt_int_op(1,OP_EQ, path_is_relative("dir"));
  2358. tt_int_op(1,OP_EQ, path_is_relative("dir\\"));
  2359. tt_int_op(1,OP_EQ, path_is_relative("dir\\a:"));
  2360. tt_int_op(1,OP_EQ, path_is_relative("dir\\a:\\"));
  2361. tt_int_op(1,OP_EQ, path_is_relative("http:\\dir"));
  2362. tt_int_op(0,OP_EQ, path_is_relative("\\dir"));
  2363. tt_int_op(0,OP_EQ, path_is_relative("a:\\dir"));
  2364. tt_int_op(0,OP_EQ, path_is_relative("z:\\dir"));
  2365. #endif
  2366. done:
  2367. ;
  2368. }
  2369. #ifdef ENABLE_MEMPOOLS
  2370. /** Run unittests for memory pool allocator */
  2371. static void
  2372. test_util_mempool(void *arg)
  2373. {
  2374. mp_pool_t *pool = NULL;
  2375. smartlist_t *allocated = NULL;
  2376. int i;
  2377. (void)arg;
  2378. pool = mp_pool_new(1, 100);
  2379. tt_assert(pool);
  2380. tt_assert(pool->new_chunk_capacity >= 100);
  2381. tt_assert(pool->item_alloc_size >= sizeof(void*)+1);
  2382. mp_pool_destroy(pool);
  2383. pool = NULL;
  2384. pool = mp_pool_new(241, 2500);
  2385. tt_assert(pool);
  2386. tt_assert(pool->new_chunk_capacity >= 10);
  2387. tt_assert(pool->item_alloc_size >= sizeof(void*)+241);
  2388. tt_int_op(pool->item_alloc_size & 0x03,OP_EQ, 0);
  2389. tt_assert(pool->new_chunk_capacity < 60);
  2390. allocated = smartlist_new();
  2391. for (i = 0; i < 20000; ++i) {
  2392. if (smartlist_len(allocated) < 20 || crypto_rand_int(2)) {
  2393. void *m = mp_pool_get(pool);
  2394. memset(m, 0x09, 241);
  2395. smartlist_add(allocated, m);
  2396. //printf("%d: %p\n", i, m);
  2397. //mp_pool_assert_ok(pool);
  2398. } else {
  2399. int idx = crypto_rand_int(smartlist_len(allocated));
  2400. void *m = smartlist_get(allocated, idx);
  2401. //printf("%d: free %p\n", i, m);
  2402. smartlist_del(allocated, idx);
  2403. mp_pool_release(m);
  2404. //mp_pool_assert_ok(pool);
  2405. }
  2406. if (crypto_rand_int(777)==0)
  2407. mp_pool_clean(pool, 1, 1);
  2408. if (i % 777)
  2409. mp_pool_assert_ok(pool);
  2410. }
  2411. done:
  2412. if (allocated) {
  2413. SMARTLIST_FOREACH(allocated, void *, m, mp_pool_release(m));
  2414. mp_pool_assert_ok(pool);
  2415. mp_pool_clean(pool, 0, 0);
  2416. mp_pool_assert_ok(pool);
  2417. smartlist_free(allocated);
  2418. }
  2419. if (pool)
  2420. mp_pool_destroy(pool);
  2421. }
  2422. #endif /* ENABLE_MEMPOOLS */
  2423. /** Run unittests for memory area allocator */
  2424. static void
  2425. test_util_memarea(void *arg)
  2426. {
  2427. memarea_t *area = memarea_new();
  2428. char *p1, *p2, *p3, *p1_orig;
  2429. void *malloced_ptr = NULL;
  2430. int i;
  2431. (void)arg;
  2432. tt_assert(area);
  2433. p1_orig = p1 = memarea_alloc(area,64);
  2434. p2 = memarea_alloc_zero(area,52);
  2435. p3 = memarea_alloc(area,11);
  2436. tt_assert(memarea_owns_ptr(area, p1));
  2437. tt_assert(memarea_owns_ptr(area, p2));
  2438. tt_assert(memarea_owns_ptr(area, p3));
  2439. /* Make sure we left enough space. */
  2440. tt_assert(p1+64 <= p2);
  2441. tt_assert(p2+52 <= p3);
  2442. /* Make sure we aligned. */
  2443. tt_int_op(((uintptr_t)p1) % sizeof(void*),OP_EQ, 0);
  2444. tt_int_op(((uintptr_t)p2) % sizeof(void*),OP_EQ, 0);
  2445. tt_int_op(((uintptr_t)p3) % sizeof(void*),OP_EQ, 0);
  2446. tt_assert(!memarea_owns_ptr(area, p3+8192));
  2447. tt_assert(!memarea_owns_ptr(area, p3+30));
  2448. tt_assert(tor_mem_is_zero(p2, 52));
  2449. /* Make sure we don't overalign. */
  2450. p1 = memarea_alloc(area, 1);
  2451. p2 = memarea_alloc(area, 1);
  2452. tt_ptr_op(p1+sizeof(void*),OP_EQ, p2);
  2453. {
  2454. malloced_ptr = tor_malloc(64);
  2455. tt_assert(!memarea_owns_ptr(area, malloced_ptr));
  2456. tor_free(malloced_ptr);
  2457. }
  2458. /* memarea_memdup */
  2459. {
  2460. malloced_ptr = tor_malloc(64);
  2461. crypto_rand((char*)malloced_ptr, 64);
  2462. p1 = memarea_memdup(area, malloced_ptr, 64);
  2463. tt_assert(p1 != malloced_ptr);
  2464. tt_mem_op(p1,OP_EQ, malloced_ptr, 64);
  2465. tor_free(malloced_ptr);
  2466. }
  2467. /* memarea_strdup. */
  2468. p1 = memarea_strdup(area,"");
  2469. p2 = memarea_strdup(area, "abcd");
  2470. tt_assert(p1);
  2471. tt_assert(p2);
  2472. tt_str_op(p1,OP_EQ, "");
  2473. tt_str_op(p2,OP_EQ, "abcd");
  2474. /* memarea_strndup. */
  2475. {
  2476. const char *s = "Ad ogni porta batte la morte e grida: il nome!";
  2477. /* (From Turandot, act 3.) */
  2478. size_t len = strlen(s);
  2479. p1 = memarea_strndup(area, s, 1000);
  2480. p2 = memarea_strndup(area, s, 10);
  2481. tt_str_op(p1,OP_EQ, s);
  2482. tt_assert(p2 >= p1 + len + 1);
  2483. tt_mem_op(s,OP_EQ, p2, 10);
  2484. tt_int_op(p2[10],OP_EQ, '\0');
  2485. p3 = memarea_strndup(area, s, len);
  2486. tt_str_op(p3,OP_EQ, s);
  2487. p3 = memarea_strndup(area, s, len-1);
  2488. tt_mem_op(s,OP_EQ, p3, len-1);
  2489. tt_int_op(p3[len-1],OP_EQ, '\0');
  2490. }
  2491. memarea_clear(area);
  2492. p1 = memarea_alloc(area, 1);
  2493. tt_ptr_op(p1,OP_EQ, p1_orig);
  2494. memarea_clear(area);
  2495. /* Check for running over an area's size. */
  2496. for (i = 0; i < 512; ++i) {
  2497. p1 = memarea_alloc(area, crypto_rand_int(5)+1);
  2498. tt_assert(memarea_owns_ptr(area, p1));
  2499. }
  2500. memarea_assert_ok(area);
  2501. /* Make sure we can allocate a too-big object. */
  2502. p1 = memarea_alloc_zero(area, 9000);
  2503. p2 = memarea_alloc_zero(area, 16);
  2504. tt_assert(memarea_owns_ptr(area, p1));
  2505. tt_assert(memarea_owns_ptr(area, p2));
  2506. done:
  2507. memarea_drop_all(area);
  2508. tor_free(malloced_ptr);
  2509. }
  2510. /** Run unit tests for utility functions to get file names relative to
  2511. * the data directory. */
  2512. static void
  2513. test_util_datadir(void *arg)
  2514. {
  2515. char buf[1024];
  2516. char *f = NULL;
  2517. char *temp_dir = NULL;
  2518. (void)arg;
  2519. temp_dir = get_datadir_fname(NULL);
  2520. f = get_datadir_fname("state");
  2521. tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir);
  2522. tt_str_op(f,OP_EQ, buf);
  2523. tor_free(f);
  2524. f = get_datadir_fname2("cache", "thingy");
  2525. tor_snprintf(buf, sizeof(buf),
  2526. "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir);
  2527. tt_str_op(f,OP_EQ, buf);
  2528. tor_free(f);
  2529. f = get_datadir_fname2_suffix("cache", "thingy", ".foo");
  2530. tor_snprintf(buf, sizeof(buf),
  2531. "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir);
  2532. tt_str_op(f,OP_EQ, buf);
  2533. tor_free(f);
  2534. f = get_datadir_fname_suffix("cache", ".foo");
  2535. tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo",
  2536. temp_dir);
  2537. tt_str_op(f,OP_EQ, buf);
  2538. done:
  2539. tor_free(f);
  2540. tor_free(temp_dir);
  2541. }
  2542. static void
  2543. test_util_strtok(void *arg)
  2544. {
  2545. char buf[128];
  2546. char buf2[128];
  2547. int i;
  2548. char *cp1, *cp2;
  2549. (void)arg;
  2550. for (i = 0; i < 3; i++) {
  2551. const char *pad1="", *pad2="";
  2552. switch (i) {
  2553. case 0:
  2554. break;
  2555. case 1:
  2556. pad1 = " ";
  2557. pad2 = "!";
  2558. break;
  2559. case 2:
  2560. pad1 = " ";
  2561. pad2 = ";!";
  2562. break;
  2563. }
  2564. tor_snprintf(buf, sizeof(buf), "%s", pad1);
  2565. tor_snprintf(buf2, sizeof(buf2), "%s", pad2);
  2566. tt_assert(NULL == tor_strtok_r_impl(buf, " ", &cp1));
  2567. tt_assert(NULL == tor_strtok_r_impl(buf2, ".!..;!", &cp2));
  2568. tor_snprintf(buf, sizeof(buf),
  2569. "%sGraved on the dark in gestures of descent%s", pad1, pad1);
  2570. tor_snprintf(buf2, sizeof(buf2),
  2571. "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2,pad2);
  2572. /* -- "Year's End", Richard Wilbur */
  2573. tt_str_op("Graved",OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  2574. tt_str_op("they",OP_EQ, tor_strtok_r_impl(buf2, ".!..;!", &cp2));
  2575. #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
  2576. #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
  2577. tt_str_op("on",OP_EQ, S1());
  2578. tt_str_op("the",OP_EQ, S1());
  2579. tt_str_op("dark",OP_EQ, S1());
  2580. tt_str_op("seemed",OP_EQ, S2());
  2581. tt_str_op("their",OP_EQ, S2());
  2582. tt_str_op("own",OP_EQ, S2());
  2583. tt_str_op("in",OP_EQ, S1());
  2584. tt_str_op("gestures",OP_EQ, S1());
  2585. tt_str_op("of",OP_EQ, S1());
  2586. tt_str_op("most",OP_EQ, S2());
  2587. tt_str_op("perfect",OP_EQ, S2());
  2588. tt_str_op("descent",OP_EQ, S1());
  2589. tt_str_op("monument",OP_EQ, S2());
  2590. tt_ptr_op(NULL,OP_EQ, S1());
  2591. tt_ptr_op(NULL,OP_EQ, S2());
  2592. }
  2593. buf[0] = 0;
  2594. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  2595. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, "!", &cp1));
  2596. strlcpy(buf, "Howdy!", sizeof(buf));
  2597. tt_str_op("Howdy",OP_EQ, tor_strtok_r_impl(buf, "!", &cp1));
  2598. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(NULL, "!", &cp1));
  2599. strlcpy(buf, " ", sizeof(buf));
  2600. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  2601. strlcpy(buf, " ", sizeof(buf));
  2602. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  2603. strlcpy(buf, "something ", sizeof(buf));
  2604. tt_str_op("something",OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  2605. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(NULL, ";", &cp1));
  2606. done:
  2607. ;
  2608. }
  2609. static void
  2610. test_util_find_str_at_start_of_line(void *ptr)
  2611. {
  2612. const char *long_string =
  2613. "howdy world. how are you? i hope it's fine.\n"
  2614. "hello kitty\n"
  2615. "third line";
  2616. char *line2 = strchr(long_string,'\n')+1;
  2617. char *line3 = strchr(line2,'\n')+1;
  2618. const char *short_string = "hello kitty\n"
  2619. "second line\n";
  2620. char *short_line2 = strchr(short_string,'\n')+1;
  2621. (void)ptr;
  2622. tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, ""));
  2623. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(short_string, "nonsense"));
  2624. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "nonsense"));
  2625. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "\n"));
  2626. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "how "));
  2627. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "kitty"));
  2628. tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, "h"));
  2629. tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, "how"));
  2630. tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "he"));
  2631. tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "hell"));
  2632. tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "hello k"));
  2633. tt_ptr_op(line2,OP_EQ,
  2634. find_str_at_start_of_line(long_string, "hello kitty\n"));
  2635. tt_ptr_op(line2,OP_EQ,
  2636. find_str_at_start_of_line(long_string, "hello kitty\nt"));
  2637. tt_ptr_op(line3,OP_EQ, find_str_at_start_of_line(long_string, "third"));
  2638. tt_ptr_op(line3,OP_EQ, find_str_at_start_of_line(long_string, "third line"));
  2639. tt_ptr_op(NULL, OP_EQ,
  2640. find_str_at_start_of_line(long_string, "third line\n"));
  2641. tt_ptr_op(short_line2,OP_EQ, find_str_at_start_of_line(short_string,
  2642. "second line\n"));
  2643. done:
  2644. ;
  2645. }
  2646. static void
  2647. test_util_string_is_C_identifier(void *ptr)
  2648. {
  2649. (void)ptr;
  2650. tt_int_op(1,OP_EQ, string_is_C_identifier("string_is_C_identifier"));
  2651. tt_int_op(1,OP_EQ, string_is_C_identifier("_string_is_C_identifier"));
  2652. tt_int_op(1,OP_EQ, string_is_C_identifier("_"));
  2653. tt_int_op(1,OP_EQ, string_is_C_identifier("i"));
  2654. tt_int_op(1,OP_EQ, string_is_C_identifier("_____"));
  2655. tt_int_op(1,OP_EQ, string_is_C_identifier("__00__"));
  2656. tt_int_op(1,OP_EQ, string_is_C_identifier("__init__"));
  2657. tt_int_op(1,OP_EQ, string_is_C_identifier("_0"));
  2658. tt_int_op(1,OP_EQ, string_is_C_identifier("_0string_is_C_identifier"));
  2659. tt_int_op(1,OP_EQ, string_is_C_identifier("_0"));
  2660. tt_int_op(0,OP_EQ, string_is_C_identifier("0_string_is_C_identifier"));
  2661. tt_int_op(0,OP_EQ, string_is_C_identifier("0"));
  2662. tt_int_op(0,OP_EQ, string_is_C_identifier(""));
  2663. tt_int_op(0,OP_EQ, string_is_C_identifier(";"));
  2664. tt_int_op(0,OP_EQ, string_is_C_identifier("i;"));
  2665. tt_int_op(0,OP_EQ, string_is_C_identifier("_;"));
  2666. tt_int_op(0,OP_EQ, string_is_C_identifier("í"));
  2667. tt_int_op(0,OP_EQ, string_is_C_identifier("ñ"));
  2668. done:
  2669. ;
  2670. }
  2671. static void
  2672. test_util_asprintf(void *ptr)
  2673. {
  2674. #define LOREMIPSUM \
  2675. "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
  2676. char *cp=NULL, *cp2=NULL;
  2677. int r;
  2678. (void)ptr;
  2679. /* simple string */
  2680. r = tor_asprintf(&cp, "simple string 100%% safe");
  2681. tt_assert(cp);
  2682. tt_str_op("simple string 100% safe",OP_EQ, cp);
  2683. tt_int_op(strlen(cp),OP_EQ, r);
  2684. tor_free(cp);
  2685. /* empty string */
  2686. r = tor_asprintf(&cp, "%s", "");
  2687. tt_assert(cp);
  2688. tt_str_op("",OP_EQ, cp);
  2689. tt_int_op(strlen(cp),OP_EQ, r);
  2690. tor_free(cp);
  2691. /* numbers (%i) */
  2692. r = tor_asprintf(&cp, "I like numbers-%2i, %i, etc.", -1, 2);
  2693. tt_assert(cp);
  2694. tt_str_op("I like numbers--1, 2, etc.",OP_EQ, cp);
  2695. tt_int_op(strlen(cp),OP_EQ, r);
  2696. /* don't free cp; next test uses it. */
  2697. /* numbers (%d) */
  2698. r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202);
  2699. tt_assert(cp2);
  2700. tt_int_op(strlen(cp2),OP_EQ, r);
  2701. tt_str_op("First=101, Second=202",OP_EQ, cp2);
  2702. tt_assert(cp != cp2);
  2703. tor_free(cp);
  2704. tor_free(cp2);
  2705. /* Glass-box test: a string exactly 128 characters long. */
  2706. r = tor_asprintf(&cp, "Lorem1: %sLorem2: %s", LOREMIPSUM, LOREMIPSUM);
  2707. tt_assert(cp);
  2708. tt_int_op(128,OP_EQ, r);
  2709. tt_int_op(cp[128], OP_EQ, '\0');
  2710. tt_str_op("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM,OP_EQ, cp);
  2711. tor_free(cp);
  2712. /* String longer than 128 characters */
  2713. r = tor_asprintf(&cp, "1: %s 2: %s 3: %s",
  2714. LOREMIPSUM, LOREMIPSUM, LOREMIPSUM);
  2715. tt_assert(cp);
  2716. tt_int_op(strlen(cp),OP_EQ, r);
  2717. tt_str_op("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM,OP_EQ, cp);
  2718. done:
  2719. tor_free(cp);
  2720. tor_free(cp2);
  2721. }
  2722. static void
  2723. test_util_listdir(void *ptr)
  2724. {
  2725. smartlist_t *dir_contents = NULL;
  2726. char *fname1=NULL, *fname2=NULL, *fname3=NULL, *dir1=NULL, *dirname=NULL;
  2727. int r;
  2728. (void)ptr;
  2729. fname1 = tor_strdup(get_fname("hopscotch"));
  2730. fname2 = tor_strdup(get_fname("mumblety-peg"));
  2731. fname3 = tor_strdup(get_fname(".hidden-file"));
  2732. dir1 = tor_strdup(get_fname("some-directory"));
  2733. dirname = tor_strdup(get_fname(NULL));
  2734. tt_int_op(0,OP_EQ, write_str_to_file(fname1, "X\n", 0));
  2735. tt_int_op(0,OP_EQ, write_str_to_file(fname2, "Y\n", 0));
  2736. tt_int_op(0,OP_EQ, write_str_to_file(fname3, "Z\n", 0));
  2737. #ifdef _WIN32
  2738. r = mkdir(dir1);
  2739. #else
  2740. r = mkdir(dir1, 0700);
  2741. #endif
  2742. if (r) {
  2743. fprintf(stderr, "Can't create directory %s:", dir1);
  2744. perror("");
  2745. exit(1);
  2746. }
  2747. dir_contents = tor_listdir(dirname);
  2748. tt_assert(dir_contents);
  2749. /* make sure that each filename is listed. */
  2750. tt_assert(smartlist_contains_string_case(dir_contents, "hopscotch"));
  2751. tt_assert(smartlist_contains_string_case(dir_contents, "mumblety-peg"));
  2752. tt_assert(smartlist_contains_string_case(dir_contents, ".hidden-file"));
  2753. tt_assert(smartlist_contains_string_case(dir_contents, "some-directory"));
  2754. tt_assert(!smartlist_contains_string(dir_contents, "."));
  2755. tt_assert(!smartlist_contains_string(dir_contents, ".."));
  2756. done:
  2757. tor_free(fname1);
  2758. tor_free(fname2);
  2759. tor_free(fname3);
  2760. tor_free(dir1);
  2761. tor_free(dirname);
  2762. if (dir_contents) {
  2763. SMARTLIST_FOREACH(dir_contents, char *, cp, tor_free(cp));
  2764. smartlist_free(dir_contents);
  2765. }
  2766. }
  2767. static void
  2768. test_util_parent_dir(void *ptr)
  2769. {
  2770. char *cp;
  2771. (void)ptr;
  2772. #define T(output,expect_ok,input) \
  2773. do { \
  2774. int ok; \
  2775. cp = tor_strdup(input); \
  2776. ok = get_parent_directory(cp); \
  2777. tt_int_op(expect_ok, OP_EQ, ok); \
  2778. if (ok==0) \
  2779. tt_str_op(output, OP_EQ, cp); \
  2780. tor_free(cp); \
  2781. } while (0);
  2782. T("/home/wombat", 0, "/home/wombat/knish");
  2783. T("/home/wombat", 0, "/home/wombat/knish/");
  2784. T("/home/wombat", 0, "/home/wombat/knish///");
  2785. T("./home/wombat", 0, "./home/wombat/knish/");
  2786. T("/", 0, "/home");
  2787. T("/", 0, "/home//");
  2788. T(".", 0, "./wombat");
  2789. T(".", 0, "./wombat/");
  2790. T(".", 0, "./wombat//");
  2791. T("wombat", 0, "wombat/foo");
  2792. T("wombat/..", 0, "wombat/../foo");
  2793. T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
  2794. T("wombat/.", 0, "wombat/./foo");
  2795. T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
  2796. T("wombat", 0, "wombat/..//");
  2797. T("wombat", 0, "wombat/foo/");
  2798. T("wombat", 0, "wombat/.foo");
  2799. T("wombat", 0, "wombat/.foo/");
  2800. T("wombat", -1, "");
  2801. T("w", -1, "");
  2802. T("wombat", 0, "wombat/knish");
  2803. T("/", 0, "/");
  2804. T("/", 0, "////");
  2805. done:
  2806. tor_free(cp);
  2807. }
  2808. static void
  2809. test_util_ftruncate(void *ptr)
  2810. {
  2811. char *buf = NULL;
  2812. const char *fname;
  2813. int fd = -1;
  2814. const char *message = "Hello world";
  2815. const char *message2 = "Hola mundo";
  2816. struct stat st;
  2817. (void) ptr;
  2818. fname = get_fname("ftruncate");
  2819. fd = tor_open_cloexec(fname, O_WRONLY|O_CREAT, 0600);
  2820. tt_int_op(fd, OP_GE, 0);
  2821. /* Make the file be there. */
  2822. tt_int_op(strlen(message), OP_EQ, write_all(fd, message, strlen(message),0));
  2823. tt_int_op((int)tor_fd_getpos(fd), OP_EQ, strlen(message));
  2824. tt_int_op(0, OP_EQ, fstat(fd, &st));
  2825. tt_int_op((int)st.st_size, OP_EQ, strlen(message));
  2826. /* Truncate and see if it got truncated */
  2827. tt_int_op(0, OP_EQ, tor_ftruncate(fd));
  2828. tt_int_op((int)tor_fd_getpos(fd), OP_EQ, 0);
  2829. tt_int_op(0, OP_EQ, fstat(fd, &st));
  2830. tt_int_op((int)st.st_size, OP_EQ, 0);
  2831. /* Replace, and see if it got replaced */
  2832. tt_int_op(strlen(message2), OP_EQ,
  2833. write_all(fd, message2, strlen(message2), 0));
  2834. tt_int_op((int)tor_fd_getpos(fd), OP_EQ, strlen(message2));
  2835. tt_int_op(0, OP_EQ, fstat(fd, &st));
  2836. tt_int_op((int)st.st_size, OP_EQ, strlen(message2));
  2837. close(fd);
  2838. fd = -1;
  2839. buf = read_file_to_str(fname, 0, NULL);
  2840. tt_str_op(message2, OP_EQ, buf);
  2841. done:
  2842. if (fd >= 0)
  2843. close(fd);
  2844. tor_free(buf);
  2845. }
  2846. #ifdef _WIN32
  2847. static void
  2848. test_util_load_win_lib(void *ptr)
  2849. {
  2850. HANDLE h = load_windows_system_library(_T("advapi32.dll"));
  2851. (void) ptr;
  2852. tt_assert(h);
  2853. done:
  2854. if (h)
  2855. FreeLibrary(h);
  2856. }
  2857. #endif
  2858. #ifndef _WIN32
  2859. static void
  2860. clear_hex_errno(char *hex_errno)
  2861. {
  2862. memset(hex_errno, '\0', HEX_ERRNO_SIZE + 1);
  2863. }
  2864. static void
  2865. test_util_exit_status(void *ptr)
  2866. {
  2867. /* Leave an extra byte for a \0 so we can do string comparison */
  2868. char hex_errno[HEX_ERRNO_SIZE + 1];
  2869. int n;
  2870. (void)ptr;
  2871. clear_hex_errno(hex_errno);
  2872. tt_str_op("",OP_EQ, hex_errno);
  2873. clear_hex_errno(hex_errno);
  2874. n = format_helper_exit_status(0, 0, hex_errno);
  2875. tt_str_op("0/0\n",OP_EQ, hex_errno);
  2876. tt_int_op(n,OP_EQ, strlen(hex_errno));
  2877. #if SIZEOF_INT == 4
  2878. clear_hex_errno(hex_errno);
  2879. n = format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
  2880. tt_str_op("0/7FFFFFFF\n",OP_EQ, hex_errno);
  2881. tt_int_op(n,OP_EQ, strlen(hex_errno));
  2882. clear_hex_errno(hex_errno);
  2883. n = format_helper_exit_status(0xFF, -0x80000000, hex_errno);
  2884. tt_str_op("FF/-80000000\n",OP_EQ, hex_errno);
  2885. tt_int_op(n,OP_EQ, strlen(hex_errno));
  2886. tt_int_op(n,OP_EQ, HEX_ERRNO_SIZE);
  2887. #elif SIZEOF_INT == 8
  2888. clear_hex_errno(hex_errno);
  2889. n = format_helper_exit_status(0, 0x7FFFFFFFFFFFFFFF, hex_errno);
  2890. tt_str_op("0/7FFFFFFFFFFFFFFF\n",OP_EQ, hex_errno);
  2891. tt_int_op(n,OP_EQ, strlen(hex_errno));
  2892. clear_hex_errno(hex_errno);
  2893. n = format_helper_exit_status(0xFF, -0x8000000000000000, hex_errno);
  2894. tt_str_op("FF/-8000000000000000\n",OP_EQ, hex_errno);
  2895. tt_int_op(n,OP_EQ, strlen(hex_errno));
  2896. tt_int_op(n,OP_EQ, HEX_ERRNO_SIZE);
  2897. #endif
  2898. clear_hex_errno(hex_errno);
  2899. n = format_helper_exit_status(0x7F, 0, hex_errno);
  2900. tt_str_op("7F/0\n",OP_EQ, hex_errno);
  2901. tt_int_op(n,OP_EQ, strlen(hex_errno));
  2902. clear_hex_errno(hex_errno);
  2903. n = format_helper_exit_status(0x08, -0x242, hex_errno);
  2904. tt_str_op("8/-242\n",OP_EQ, hex_errno);
  2905. tt_int_op(n,OP_EQ, strlen(hex_errno));
  2906. clear_hex_errno(hex_errno);
  2907. tt_str_op("",OP_EQ, hex_errno);
  2908. done:
  2909. ;
  2910. }
  2911. #endif
  2912. #ifndef _WIN32
  2913. /* Check that fgets with a non-blocking pipe returns partial lines and sets
  2914. * EAGAIN, returns full lines and sets no error, and returns NULL on EOF and
  2915. * sets no error */
  2916. static void
  2917. test_util_fgets_eagain(void *ptr)
  2918. {
  2919. int test_pipe[2] = {-1, -1};
  2920. int retval;
  2921. ssize_t retlen;
  2922. char *retptr;
  2923. FILE *test_stream = NULL;
  2924. char buf[4] = { 0 };
  2925. (void)ptr;
  2926. errno = 0;
  2927. /* Set up a pipe to test on */
  2928. retval = pipe(test_pipe);
  2929. tt_int_op(retval, OP_EQ, 0);
  2930. /* Set up the read-end to be non-blocking */
  2931. retval = fcntl(test_pipe[0], F_SETFL, O_NONBLOCK);
  2932. tt_int_op(retval, OP_EQ, 0);
  2933. /* Open it as a stdio stream */
  2934. test_stream = fdopen(test_pipe[0], "r");
  2935. tt_ptr_op(test_stream, OP_NE, NULL);
  2936. /* Send in a partial line */
  2937. retlen = write(test_pipe[1], "A", 1);
  2938. tt_int_op(retlen, OP_EQ, 1);
  2939. retptr = fgets(buf, sizeof(buf), test_stream);
  2940. tt_int_op(errno, OP_EQ, EAGAIN);
  2941. tt_ptr_op(retptr, OP_EQ, buf);
  2942. tt_str_op(buf, OP_EQ, "A");
  2943. errno = 0;
  2944. /* Send in the rest */
  2945. retlen = write(test_pipe[1], "B\n", 2);
  2946. tt_int_op(retlen, OP_EQ, 2);
  2947. retptr = fgets(buf, sizeof(buf), test_stream);
  2948. tt_int_op(errno, OP_EQ, 0);
  2949. tt_ptr_op(retptr, OP_EQ, buf);
  2950. tt_str_op(buf, OP_EQ, "B\n");
  2951. errno = 0;
  2952. /* Send in a full line */
  2953. retlen = write(test_pipe[1], "CD\n", 3);
  2954. tt_int_op(retlen, OP_EQ, 3);
  2955. retptr = fgets(buf, sizeof(buf), test_stream);
  2956. tt_int_op(errno, OP_EQ, 0);
  2957. tt_ptr_op(retptr, OP_EQ, buf);
  2958. tt_str_op(buf, OP_EQ, "CD\n");
  2959. errno = 0;
  2960. /* Send in a partial line */
  2961. retlen = write(test_pipe[1], "E", 1);
  2962. tt_int_op(retlen, OP_EQ, 1);
  2963. retptr = fgets(buf, sizeof(buf), test_stream);
  2964. tt_int_op(errno, OP_EQ, EAGAIN);
  2965. tt_ptr_op(retptr, OP_EQ, buf);
  2966. tt_str_op(buf, OP_EQ, "E");
  2967. errno = 0;
  2968. /* Send in the rest */
  2969. retlen = write(test_pipe[1], "F\n", 2);
  2970. tt_int_op(retlen, OP_EQ, 2);
  2971. retptr = fgets(buf, sizeof(buf), test_stream);
  2972. tt_int_op(errno, OP_EQ, 0);
  2973. tt_ptr_op(retptr, OP_EQ, buf);
  2974. tt_str_op(buf, OP_EQ, "F\n");
  2975. errno = 0;
  2976. /* Send in a full line and close */
  2977. retlen = write(test_pipe[1], "GH", 2);
  2978. tt_int_op(retlen, OP_EQ, 2);
  2979. retval = close(test_pipe[1]);
  2980. tt_int_op(retval, OP_EQ, 0);
  2981. test_pipe[1] = -1;
  2982. retptr = fgets(buf, sizeof(buf), test_stream);
  2983. tt_int_op(errno, OP_EQ, 0);
  2984. tt_ptr_op(retptr, OP_EQ, buf);
  2985. tt_str_op(buf, OP_EQ, "GH");
  2986. errno = 0;
  2987. /* Check for EOF */
  2988. retptr = fgets(buf, sizeof(buf), test_stream);
  2989. tt_int_op(errno, OP_EQ, 0);
  2990. tt_ptr_op(retptr, OP_EQ, NULL);
  2991. retval = feof(test_stream);
  2992. tt_int_op(retval, OP_NE, 0);
  2993. errno = 0;
  2994. /* Check that buf is unchanged according to C99 and C11 */
  2995. tt_str_op(buf, OP_EQ, "GH");
  2996. done:
  2997. if (test_stream != NULL)
  2998. fclose(test_stream);
  2999. if (test_pipe[0] != -1)
  3000. close(test_pipe[0]);
  3001. if (test_pipe[1] != -1)
  3002. close(test_pipe[1]);
  3003. }
  3004. #endif
  3005. #ifndef BUILDDIR
  3006. #define BUILDDIR "."
  3007. #endif
  3008. #ifdef _WIN32
  3009. #define notify_pending_waitpid_callbacks() STMT_NIL
  3010. #define TEST_CHILD "test-child.exe"
  3011. #define EOL "\r\n"
  3012. #else
  3013. #define TEST_CHILD (BUILDDIR "/src/test/test-child")
  3014. #define EOL "\n"
  3015. #endif
  3016. #ifdef _WIN32
  3017. /* I've assumed Windows doesn't have the gap between fork and exec
  3018. * that causes the race condition on unix-like platforms */
  3019. #define MATCH_PROCESS_STATUS(s1,s2) ((s1) == (s2))
  3020. #else
  3021. /* work around a race condition of the timing of SIGCHLD handler updates
  3022. * to the process_handle's fields, and checks of those fields
  3023. *
  3024. * TODO: Once we can signal failure to exec, change PROCESS_STATUS_RUNNING to
  3025. * PROCESS_STATUS_ERROR (and similarly with *_OR_NOTRUNNING) */
  3026. #define PROCESS_STATUS_RUNNING_OR_NOTRUNNING (PROCESS_STATUS_RUNNING+1)
  3027. #define IS_RUNNING_OR_NOTRUNNING(s) \
  3028. ((s) == PROCESS_STATUS_RUNNING || (s) == PROCESS_STATUS_NOTRUNNING)
  3029. /* well, this is ugly */
  3030. #define MATCH_PROCESS_STATUS(s1,s2) \
  3031. ( (s1) == (s2) \
  3032. ||((s1) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \
  3033. && IS_RUNNING_OR_NOTRUNNING(s2)) \
  3034. ||((s2) == PROCESS_STATUS_RUNNING_OR_NOTRUNNING \
  3035. && IS_RUNNING_OR_NOTRUNNING(s1)))
  3036. #endif // _WIN32
  3037. /** Helper function for testing tor_spawn_background */
  3038. static void
  3039. run_util_spawn_background(const char *argv[], const char *expected_out,
  3040. const char *expected_err, int expected_exit,
  3041. int expected_status)
  3042. {
  3043. int retval, exit_code;
  3044. ssize_t pos;
  3045. process_handle_t *process_handle=NULL;
  3046. char stdout_buf[100], stderr_buf[100];
  3047. int status;
  3048. /* Start the program */
  3049. #ifdef _WIN32
  3050. status = tor_spawn_background(NULL, argv, NULL, &process_handle);
  3051. #else
  3052. status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
  3053. #endif
  3054. notify_pending_waitpid_callbacks();
  3055. /* the race condition doesn't affect status,
  3056. * because status isn't updated by the SIGCHLD handler,
  3057. * but we still need to handle PROCESS_STATUS_RUNNING_OR_NOTRUNNING */
  3058. tt_assert(MATCH_PROCESS_STATUS(expected_status, status));
  3059. if (status == PROCESS_STATUS_ERROR) {
  3060. tt_ptr_op(process_handle, OP_EQ, NULL);
  3061. return;
  3062. }
  3063. tt_assert(process_handle != NULL);
  3064. /* When a spawned process forks, fails, then exits very quickly,
  3065. * (this typically occurs when exec fails)
  3066. * there is a race condition between the SIGCHLD handler
  3067. * updating the process_handle's fields, and this test
  3068. * checking the process status in those fields.
  3069. * The SIGCHLD update can occur before or after the code below executes.
  3070. * This causes intermittent failures in spawn_background_fail(),
  3071. * typically when the machine is under load.
  3072. * We use PROCESS_STATUS_RUNNING_OR_NOTRUNNING to avoid this issue. */
  3073. /* the race condition affects the change in
  3074. * process_handle->status from RUNNING to NOTRUNNING */
  3075. tt_assert(MATCH_PROCESS_STATUS(expected_status, process_handle->status));
  3076. #ifndef _WIN32
  3077. notify_pending_waitpid_callbacks();
  3078. /* the race condition affects the change in
  3079. * process_handle->waitpid_cb to NULL,
  3080. * so we skip the check if expected_status is ambiguous,
  3081. * that is, PROCESS_STATUS_RUNNING_OR_NOTRUNNING */
  3082. tt_assert(process_handle->waitpid_cb != NULL
  3083. || expected_status == PROCESS_STATUS_RUNNING_OR_NOTRUNNING);
  3084. #endif
  3085. #ifdef _WIN32
  3086. tt_assert(process_handle->stdout_pipe != INVALID_HANDLE_VALUE);
  3087. tt_assert(process_handle->stderr_pipe != INVALID_HANDLE_VALUE);
  3088. #else
  3089. tt_assert(process_handle->stdout_pipe >= 0);
  3090. tt_assert(process_handle->stderr_pipe >= 0);
  3091. #endif
  3092. /* Check stdout */
  3093. pos = tor_read_all_from_process_stdout(process_handle, stdout_buf,
  3094. sizeof(stdout_buf) - 1);
  3095. tt_assert(pos >= 0);
  3096. stdout_buf[pos] = '\0';
  3097. tt_int_op(strlen(expected_out),OP_EQ, pos);
  3098. tt_str_op(expected_out,OP_EQ, stdout_buf);
  3099. notify_pending_waitpid_callbacks();
  3100. /* Check it terminated correctly */
  3101. retval = tor_get_exit_code(process_handle, 1, &exit_code);
  3102. tt_int_op(PROCESS_EXIT_EXITED,OP_EQ, retval);
  3103. tt_int_op(expected_exit,OP_EQ, exit_code);
  3104. // TODO: Make test-child exit with something other than 0
  3105. #ifndef _WIN32
  3106. notify_pending_waitpid_callbacks();
  3107. tt_ptr_op(process_handle->waitpid_cb, OP_EQ, NULL);
  3108. #endif
  3109. /* Check stderr */
  3110. pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
  3111. sizeof(stderr_buf) - 1);
  3112. tt_assert(pos >= 0);
  3113. stderr_buf[pos] = '\0';
  3114. tt_str_op(expected_err,OP_EQ, stderr_buf);
  3115. tt_int_op(strlen(expected_err),OP_EQ, pos);
  3116. notify_pending_waitpid_callbacks();
  3117. done:
  3118. if (process_handle)
  3119. tor_process_handle_destroy(process_handle, 1);
  3120. }
  3121. /** Check that we can launch a process and read the output */
  3122. static void
  3123. test_util_spawn_background_ok(void *ptr)
  3124. {
  3125. const char *argv[] = {TEST_CHILD, "--test", NULL};
  3126. const char *expected_out = "OUT"EOL "--test"EOL "SLEEPING"EOL "DONE" EOL;
  3127. const char *expected_err = "ERR"EOL;
  3128. (void)ptr;
  3129. run_util_spawn_background(argv, expected_out, expected_err, 0,
  3130. PROCESS_STATUS_RUNNING);
  3131. }
  3132. /** Check that failing to find the executable works as expected */
  3133. static void
  3134. test_util_spawn_background_fail(void *ptr)
  3135. {
  3136. const char *argv[] = {BUILDDIR "/src/test/no-such-file", "--test", NULL};
  3137. const char *expected_err = "";
  3138. char expected_out[1024];
  3139. char code[32];
  3140. #ifdef _WIN32
  3141. const int expected_status = PROCESS_STATUS_ERROR;
  3142. #else
  3143. /* TODO: Once we can signal failure to exec, set this to be
  3144. * PROCESS_STATUS_RUNNING_OR_ERROR */
  3145. const int expected_status = PROCESS_STATUS_RUNNING_OR_NOTRUNNING;
  3146. #endif
  3147. memset(expected_out, 0xf0, sizeof(expected_out));
  3148. memset(code, 0xf0, sizeof(code));
  3149. (void)ptr;
  3150. tor_snprintf(code, sizeof(code), "%x/%x",
  3151. 9 /* CHILD_STATE_FAILEXEC */ , ENOENT);
  3152. tor_snprintf(expected_out, sizeof(expected_out),
  3153. "ERR: Failed to spawn background process - code %s\n", code);
  3154. run_util_spawn_background(argv, expected_out, expected_err, 255,
  3155. expected_status);
  3156. }
  3157. /** Test that reading from a handle returns a partial read rather than
  3158. * blocking */
  3159. static void
  3160. test_util_spawn_background_partial_read_impl(int exit_early)
  3161. {
  3162. const int expected_exit = 0;
  3163. const int expected_status = PROCESS_STATUS_RUNNING;
  3164. int retval, exit_code;
  3165. ssize_t pos = -1;
  3166. process_handle_t *process_handle=NULL;
  3167. int status;
  3168. char stdout_buf[100], stderr_buf[100];
  3169. const char *argv[] = {TEST_CHILD, "--test", NULL};
  3170. const char *expected_out[] = { "OUT" EOL "--test" EOL "SLEEPING" EOL,
  3171. "DONE" EOL,
  3172. NULL };
  3173. const char *expected_err = "ERR" EOL;
  3174. #ifndef _WIN32
  3175. int eof = 0;
  3176. #endif
  3177. int expected_out_ctr;
  3178. if (exit_early) {
  3179. argv[1] = "--hang";
  3180. expected_out[0] = "OUT"EOL "--hang"EOL "SLEEPING" EOL;
  3181. }
  3182. /* Start the program */
  3183. #ifdef _WIN32
  3184. status = tor_spawn_background(NULL, argv, NULL, &process_handle);
  3185. #else
  3186. status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
  3187. #endif
  3188. tt_int_op(expected_status,OP_EQ, status);
  3189. tt_assert(process_handle);
  3190. tt_int_op(expected_status,OP_EQ, process_handle->status);
  3191. /* Check stdout */
  3192. for (expected_out_ctr = 0; expected_out[expected_out_ctr] != NULL;) {
  3193. #ifdef _WIN32
  3194. pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
  3195. sizeof(stdout_buf) - 1, NULL);
  3196. #else
  3197. /* Check that we didn't read the end of file last time */
  3198. tt_assert(!eof);
  3199. pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
  3200. sizeof(stdout_buf) - 1, NULL, &eof);
  3201. #endif
  3202. log_info(LD_GENERAL, "tor_read_all_handle() returned %d", (int)pos);
  3203. /* We would have blocked, keep on trying */
  3204. if (0 == pos)
  3205. continue;
  3206. tt_assert(pos > 0);
  3207. stdout_buf[pos] = '\0';
  3208. tt_str_op(expected_out[expected_out_ctr],OP_EQ, stdout_buf);
  3209. tt_int_op(strlen(expected_out[expected_out_ctr]),OP_EQ, pos);
  3210. expected_out_ctr++;
  3211. }
  3212. if (exit_early) {
  3213. tor_process_handle_destroy(process_handle, 1);
  3214. process_handle = NULL;
  3215. goto done;
  3216. }
  3217. /* The process should have exited without writing more */
  3218. #ifdef _WIN32
  3219. pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
  3220. sizeof(stdout_buf) - 1,
  3221. process_handle);
  3222. tt_int_op(0,OP_EQ, pos);
  3223. #else
  3224. if (!eof) {
  3225. /* We should have got all the data, but maybe not the EOF flag */
  3226. pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
  3227. sizeof(stdout_buf) - 1,
  3228. process_handle, &eof);
  3229. tt_int_op(0,OP_EQ, pos);
  3230. tt_assert(eof);
  3231. }
  3232. /* Otherwise, we got the EOF on the last read */
  3233. #endif
  3234. /* Check it terminated correctly */
  3235. retval = tor_get_exit_code(process_handle, 1, &exit_code);
  3236. tt_int_op(PROCESS_EXIT_EXITED,OP_EQ, retval);
  3237. tt_int_op(expected_exit,OP_EQ, exit_code);
  3238. // TODO: Make test-child exit with something other than 0
  3239. /* Check stderr */
  3240. pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
  3241. sizeof(stderr_buf) - 1);
  3242. tt_assert(pos >= 0);
  3243. stderr_buf[pos] = '\0';
  3244. tt_str_op(expected_err,OP_EQ, stderr_buf);
  3245. tt_int_op(strlen(expected_err),OP_EQ, pos);
  3246. done:
  3247. tor_process_handle_destroy(process_handle, 1);
  3248. }
  3249. static void
  3250. test_util_spawn_background_partial_read(void *arg)
  3251. {
  3252. (void)arg;
  3253. test_util_spawn_background_partial_read_impl(0);
  3254. }
  3255. static void
  3256. test_util_spawn_background_exit_early(void *arg)
  3257. {
  3258. (void)arg;
  3259. test_util_spawn_background_partial_read_impl(1);
  3260. }
  3261. static void
  3262. test_util_spawn_background_waitpid_notify(void *arg)
  3263. {
  3264. int retval, exit_code;
  3265. process_handle_t *process_handle=NULL;
  3266. int status;
  3267. int ms_timer;
  3268. const char *argv[] = {TEST_CHILD, "--fast", NULL};
  3269. (void) arg;
  3270. #ifdef _WIN32
  3271. status = tor_spawn_background(NULL, argv, NULL, &process_handle);
  3272. #else
  3273. status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
  3274. #endif
  3275. tt_int_op(status, OP_EQ, PROCESS_STATUS_RUNNING);
  3276. tt_ptr_op(process_handle, OP_NE, NULL);
  3277. /* We're not going to look at the stdout/stderr output this time. Instead,
  3278. * we're testing whether notify_pending_waitpid_calbacks() can report the
  3279. * process exit (on unix) and/or whether tor_get_exit_code() can notice it
  3280. * (on windows) */
  3281. #ifndef _WIN32
  3282. ms_timer = 30*1000;
  3283. tt_ptr_op(process_handle->waitpid_cb, OP_NE, NULL);
  3284. while (process_handle->waitpid_cb && ms_timer > 0) {
  3285. tor_sleep_msec(100);
  3286. ms_timer -= 100;
  3287. notify_pending_waitpid_callbacks();
  3288. }
  3289. tt_int_op(ms_timer, OP_GT, 0);
  3290. tt_ptr_op(process_handle->waitpid_cb, OP_EQ, NULL);
  3291. #endif
  3292. ms_timer = 30*1000;
  3293. while (((retval = tor_get_exit_code(process_handle, 0, &exit_code))
  3294. == PROCESS_EXIT_RUNNING) && ms_timer > 0) {
  3295. tor_sleep_msec(100);
  3296. ms_timer -= 100;
  3297. }
  3298. tt_int_op(ms_timer, OP_GT, 0);
  3299. tt_int_op(retval, OP_EQ, PROCESS_EXIT_EXITED);
  3300. done:
  3301. tor_process_handle_destroy(process_handle, 1);
  3302. }
  3303. #undef TEST_CHILD
  3304. #undef EOL
  3305. #undef MATCH_PROCESS_STATUS
  3306. #ifndef _WIN32
  3307. #undef PROCESS_STATUS_RUNNING_OR_NOTRUNNING
  3308. #undef IS_RUNNING_OR_NOTRUNNING
  3309. #endif
  3310. /**
  3311. * Test for format_hex_number_sigsafe()
  3312. */
  3313. static void
  3314. test_util_format_hex_number(void *ptr)
  3315. {
  3316. int i, len;
  3317. char buf[33];
  3318. const struct {
  3319. const char *str;
  3320. unsigned int x;
  3321. } test_data[] = {
  3322. {"0", 0},
  3323. {"1", 1},
  3324. {"273A", 0x273a},
  3325. {"FFFF", 0xffff},
  3326. {"7FFFFFFF", 0x7fffffff},
  3327. {"FFFFFFFF", 0xffffffff},
  3328. #if UINT_MAX >= 0xffffffff
  3329. {"31BC421D", 0x31bc421d},
  3330. {"FFFFFFFF", 0xffffffff},
  3331. #endif
  3332. {NULL, 0}
  3333. };
  3334. (void)ptr;
  3335. for (i = 0; test_data[i].str != NULL; ++i) {
  3336. len = format_hex_number_sigsafe(test_data[i].x, buf, sizeof(buf));
  3337. tt_int_op(len,OP_NE, 0);
  3338. tt_int_op(len,OP_EQ, strlen(buf));
  3339. tt_str_op(buf,OP_EQ, test_data[i].str);
  3340. }
  3341. tt_int_op(4,OP_EQ, format_hex_number_sigsafe(0xffff, buf, 5));
  3342. tt_str_op(buf,OP_EQ, "FFFF");
  3343. tt_int_op(0,OP_EQ, format_hex_number_sigsafe(0xffff, buf, 4));
  3344. tt_int_op(0,OP_EQ, format_hex_number_sigsafe(0, buf, 1));
  3345. done:
  3346. return;
  3347. }
  3348. /**
  3349. * Test for format_hex_number_sigsafe()
  3350. */
  3351. static void
  3352. test_util_format_dec_number(void *ptr)
  3353. {
  3354. int i, len;
  3355. char buf[33];
  3356. const struct {
  3357. const char *str;
  3358. unsigned int x;
  3359. } test_data[] = {
  3360. {"0", 0},
  3361. {"1", 1},
  3362. {"1234", 1234},
  3363. {"12345678", 12345678},
  3364. {"99999999", 99999999},
  3365. {"100000000", 100000000},
  3366. {"4294967295", 4294967295u},
  3367. #if UINT_MAX > 0xffffffff
  3368. {"18446744073709551615", 18446744073709551615u },
  3369. #endif
  3370. {NULL, 0}
  3371. };
  3372. (void)ptr;
  3373. for (i = 0; test_data[i].str != NULL; ++i) {
  3374. len = format_dec_number_sigsafe(test_data[i].x, buf, sizeof(buf));
  3375. tt_int_op(len,OP_NE, 0);
  3376. tt_int_op(len,OP_EQ, strlen(buf));
  3377. tt_str_op(buf,OP_EQ, test_data[i].str);
  3378. len = format_dec_number_sigsafe(test_data[i].x, buf,
  3379. (int)(strlen(test_data[i].str) + 1));
  3380. tt_int_op(len,OP_EQ, strlen(buf));
  3381. tt_str_op(buf,OP_EQ, test_data[i].str);
  3382. }
  3383. tt_int_op(4,OP_EQ, format_dec_number_sigsafe(7331, buf, 5));
  3384. tt_str_op(buf,OP_EQ, "7331");
  3385. tt_int_op(0,OP_EQ, format_dec_number_sigsafe(7331, buf, 4));
  3386. tt_int_op(1,OP_EQ, format_dec_number_sigsafe(0, buf, 2));
  3387. tt_int_op(0,OP_EQ, format_dec_number_sigsafe(0, buf, 1));
  3388. done:
  3389. return;
  3390. }
  3391. /**
  3392. * Test that we can properly format a Windows command line
  3393. */
  3394. static void
  3395. test_util_join_win_cmdline(void *ptr)
  3396. {
  3397. /* Based on some test cases from "Parsing C++ Command-Line Arguments" in
  3398. * MSDN but we don't exercise all quoting rules because tor_join_win_cmdline
  3399. * will try to only generate simple cases for the child process to parse;
  3400. * i.e. we never embed quoted strings in arguments. */
  3401. const char *argvs[][4] = {
  3402. {"a", "bb", "CCC", NULL}, // Normal
  3403. {NULL, NULL, NULL, NULL}, // Empty argument list
  3404. {"", NULL, NULL, NULL}, // Empty argument
  3405. {"\"a", "b\"b", "CCC\"", NULL}, // Quotes
  3406. {"a\tbc", "dd dd", "E", NULL}, // Whitespace
  3407. {"a\\\\\\b", "de fg", "H", NULL}, // Backslashes
  3408. {"a\\\"b", "\\c", "D\\", NULL}, // Backslashes before quote
  3409. {"a\\\\b c", "d", "E", NULL}, // Backslashes not before quote
  3410. { NULL } // Terminator
  3411. };
  3412. const char *cmdlines[] = {
  3413. "a bb CCC",
  3414. "",
  3415. "\"\"",
  3416. "\\\"a b\\\"b CCC\\\"",
  3417. "\"a\tbc\" \"dd dd\" E",
  3418. "a\\\\\\b \"de fg\" H",
  3419. "a\\\\\\\"b \\c D\\",
  3420. "\"a\\\\b c\" d E",
  3421. NULL // Terminator
  3422. };
  3423. int i;
  3424. char *joined_argv = NULL;
  3425. (void)ptr;
  3426. for (i=0; cmdlines[i]!=NULL; i++) {
  3427. log_info(LD_GENERAL, "Joining argvs[%d], expecting <%s>", i, cmdlines[i]);
  3428. joined_argv = tor_join_win_cmdline(argvs[i]);
  3429. tt_str_op(cmdlines[i],OP_EQ, joined_argv);
  3430. tor_free(joined_argv);
  3431. }
  3432. done:
  3433. tor_free(joined_argv);
  3434. }
  3435. #define MAX_SPLIT_LINE_COUNT 4
  3436. struct split_lines_test_t {
  3437. const char *orig_line; // Line to be split (may contain \0's)
  3438. int orig_length; // Length of orig_line
  3439. const char *split_line[MAX_SPLIT_LINE_COUNT]; // Split lines
  3440. };
  3441. /**
  3442. * Test that we properly split a buffer into lines
  3443. */
  3444. static void
  3445. test_util_split_lines(void *ptr)
  3446. {
  3447. /* Test cases. orig_line of last test case must be NULL.
  3448. * The last element of split_line[i] must be NULL. */
  3449. struct split_lines_test_t tests[] = {
  3450. {"", 0, {NULL}},
  3451. {"foo", 3, {"foo", NULL}},
  3452. {"\n\rfoo\n\rbar\r\n", 12, {"foo", "bar", NULL}},
  3453. {"fo o\r\nb\tar", 10, {"fo o", "b.ar", NULL}},
  3454. {"\x0f""f\0o\0\n\x01""b\0r\0\r", 12, {".f.o.", ".b.r.", NULL}},
  3455. {"line 1\r\nline 2", 14, {"line 1", "line 2", NULL}},
  3456. {"line 1\r\n\r\nline 2", 16, {"line 1", "line 2", NULL}},
  3457. {"line 1\r\n\r\r\r\nline 2", 18, {"line 1", "line 2", NULL}},
  3458. {"line 1\r\n\n\n\n\rline 2", 18, {"line 1", "line 2", NULL}},
  3459. {"line 1\r\n\r\t\r\nline 3", 18, {"line 1", ".", "line 3", NULL}},
  3460. {"\n\t\r\t\nline 3", 11, {".", ".", "line 3", NULL}},
  3461. {NULL, 0, { NULL }}
  3462. };
  3463. int i, j;
  3464. char *orig_line=NULL;
  3465. smartlist_t *sl=NULL;
  3466. (void)ptr;
  3467. for (i=0; tests[i].orig_line; i++) {
  3468. sl = smartlist_new();
  3469. /* Allocate space for string and trailing NULL */
  3470. orig_line = tor_memdup(tests[i].orig_line, tests[i].orig_length + 1);
  3471. tor_split_lines(sl, orig_line, tests[i].orig_length);
  3472. j = 0;
  3473. log_info(LD_GENERAL, "Splitting test %d of length %d",
  3474. i, tests[i].orig_length);
  3475. SMARTLIST_FOREACH_BEGIN(sl, const char *, line) {
  3476. /* Check we have not got too many lines */
  3477. tt_int_op(MAX_SPLIT_LINE_COUNT, OP_GT, j);
  3478. /* Check that there actually should be a line here */
  3479. tt_assert(tests[i].split_line[j] != NULL);
  3480. log_info(LD_GENERAL, "Line %d of test %d, should be <%s>",
  3481. j, i, tests[i].split_line[j]);
  3482. /* Check that the line is as expected */
  3483. tt_str_op(line,OP_EQ, tests[i].split_line[j]);
  3484. j++;
  3485. } SMARTLIST_FOREACH_END(line);
  3486. /* Check that we didn't miss some lines */
  3487. tt_ptr_op(NULL,OP_EQ, tests[i].split_line[j]);
  3488. tor_free(orig_line);
  3489. smartlist_free(sl);
  3490. sl = NULL;
  3491. }
  3492. done:
  3493. tor_free(orig_line);
  3494. smartlist_free(sl);
  3495. }
  3496. static void
  3497. test_util_di_ops(void *arg)
  3498. {
  3499. #define LT -1
  3500. #define GT 1
  3501. #define EQ 0
  3502. const struct {
  3503. const char *a; int want_sign; const char *b;
  3504. } examples[] = {
  3505. { "Foo", EQ, "Foo" },
  3506. { "foo", GT, "bar", },
  3507. { "foobar", EQ ,"foobar" },
  3508. { "foobar", LT, "foobaw" },
  3509. { "foobar", GT, "f00bar" },
  3510. { "foobar", GT, "boobar" },
  3511. { "", EQ, "" },
  3512. { NULL, 0, NULL },
  3513. };
  3514. int i;
  3515. (void)arg;
  3516. for (i = 0; examples[i].a; ++i) {
  3517. size_t len = strlen(examples[i].a);
  3518. int eq1, eq2, neq1, neq2, cmp1, cmp2;
  3519. tt_int_op(len,OP_EQ, strlen(examples[i].b));
  3520. /* We do all of the operations, with operands in both orders. */
  3521. eq1 = tor_memeq(examples[i].a, examples[i].b, len);
  3522. eq2 = tor_memeq(examples[i].b, examples[i].a, len);
  3523. neq1 = tor_memneq(examples[i].a, examples[i].b, len);
  3524. neq2 = tor_memneq(examples[i].b, examples[i].a, len);
  3525. cmp1 = tor_memcmp(examples[i].a, examples[i].b, len);
  3526. cmp2 = tor_memcmp(examples[i].b, examples[i].a, len);
  3527. /* Check for correctness of cmp1 */
  3528. if (cmp1 < 0 && examples[i].want_sign != LT)
  3529. TT_DIE(("Assertion failed."));
  3530. else if (cmp1 > 0 && examples[i].want_sign != GT)
  3531. TT_DIE(("Assertion failed."));
  3532. else if (cmp1 == 0 && examples[i].want_sign != EQ)
  3533. TT_DIE(("Assertion failed."));
  3534. /* Check for consistency of everything else with cmp1 */
  3535. tt_int_op(eq1,OP_EQ, eq2);
  3536. tt_int_op(neq1,OP_EQ, neq2);
  3537. tt_int_op(cmp1,OP_EQ, -cmp2);
  3538. tt_int_op(eq1,OP_EQ, cmp1 == 0);
  3539. tt_int_op(neq1,OP_EQ, !eq1);
  3540. }
  3541. {
  3542. uint8_t zz = 0;
  3543. uint8_t ii = 0;
  3544. int z;
  3545. /* exhaustively test tor_memeq and tor_memcmp
  3546. * against each possible single-byte numeric difference
  3547. * some arithmetic bugs only appear with certain bit patterns */
  3548. for (z = 0; z < 256; z++) {
  3549. for (i = 0; i < 256; i++) {
  3550. ii = (uint8_t)i;
  3551. zz = (uint8_t)z;
  3552. tt_int_op(tor_memeq(&zz, &ii, 1),OP_EQ, zz == ii);
  3553. tt_int_op(tor_memcmp(&zz, &ii, 1) > 0 ? GT : EQ,OP_EQ,
  3554. zz > ii ? GT : EQ);
  3555. tt_int_op(tor_memcmp(&ii, &zz, 1) < 0 ? LT : EQ,OP_EQ,
  3556. ii < zz ? LT : EQ);
  3557. }
  3558. }
  3559. }
  3560. tt_int_op(1, OP_EQ, safe_mem_is_zero("", 0));
  3561. tt_int_op(1, OP_EQ, safe_mem_is_zero("", 1));
  3562. tt_int_op(0, OP_EQ, safe_mem_is_zero("a", 1));
  3563. tt_int_op(0, OP_EQ, safe_mem_is_zero("a", 2));
  3564. tt_int_op(0, OP_EQ, safe_mem_is_zero("\0a", 2));
  3565. tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0a", 2));
  3566. tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
  3567. tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
  3568. tt_int_op(0, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
  3569. done:
  3570. ;
  3571. }
  3572. /**
  3573. * Test counting high bits
  3574. */
  3575. static void
  3576. test_util_n_bits_set(void *ptr)
  3577. {
  3578. (void)ptr;
  3579. tt_int_op(0,OP_EQ, n_bits_set_u8(0));
  3580. tt_int_op(1,OP_EQ, n_bits_set_u8(1));
  3581. tt_int_op(3,OP_EQ, n_bits_set_u8(7));
  3582. tt_int_op(1,OP_EQ, n_bits_set_u8(8));
  3583. tt_int_op(2,OP_EQ, n_bits_set_u8(129));
  3584. tt_int_op(8,OP_EQ, n_bits_set_u8(255));
  3585. done:
  3586. ;
  3587. }
  3588. /**
  3589. * Test LHS whitespace (and comment) eater
  3590. */
  3591. static void
  3592. test_util_eat_whitespace(void *ptr)
  3593. {
  3594. const char ws[] = { ' ', '\t', '\r' }; /* Except NL */
  3595. char str[80];
  3596. size_t i;
  3597. (void)ptr;
  3598. /* Try one leading ws */
  3599. strlcpy(str, "fuubaar", sizeof(str));
  3600. for (i = 0; i < sizeof(ws); ++i) {
  3601. str[0] = ws[i];
  3602. tt_ptr_op(str + 1,OP_EQ, eat_whitespace(str));
  3603. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
  3604. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_no_nl(str));
  3605. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3606. }
  3607. str[0] = '\n';
  3608. tt_ptr_op(str + 1,OP_EQ, eat_whitespace(str));
  3609. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
  3610. tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
  3611. tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3612. /* Empty string */
  3613. strlcpy(str, "", sizeof(str));
  3614. tt_ptr_op(str,OP_EQ, eat_whitespace(str));
  3615. tt_ptr_op(str,OP_EQ, eat_whitespace_eos(str, str));
  3616. tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
  3617. tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str));
  3618. /* Only ws */
  3619. strlcpy(str, " \t\r\n", sizeof(str));
  3620. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
  3621. tt_ptr_op(str + strlen(str),OP_EQ,
  3622. eat_whitespace_eos(str, str + strlen(str)));
  3623. tt_ptr_op(str + strlen(str) - 1,OP_EQ,
  3624. eat_whitespace_no_nl(str));
  3625. tt_ptr_op(str + strlen(str) - 1,OP_EQ,
  3626. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3627. strlcpy(str, " \t\r ", sizeof(str));
  3628. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
  3629. tt_ptr_op(str + strlen(str),OP_EQ,
  3630. eat_whitespace_eos(str, str + strlen(str)));
  3631. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace_no_nl(str));
  3632. tt_ptr_op(str + strlen(str),OP_EQ,
  3633. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3634. /* Multiple ws */
  3635. strlcpy(str, "fuubaar", sizeof(str));
  3636. for (i = 0; i < sizeof(ws); ++i)
  3637. str[i] = ws[i];
  3638. tt_ptr_op(str + sizeof(ws),OP_EQ, eat_whitespace(str));
  3639. tt_ptr_op(str + sizeof(ws),OP_EQ,
  3640. eat_whitespace_eos(str, str + strlen(str)));
  3641. tt_ptr_op(str + sizeof(ws),OP_EQ, eat_whitespace_no_nl(str));
  3642. tt_ptr_op(str + sizeof(ws),OP_EQ,
  3643. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3644. /* Eat comment */
  3645. strlcpy(str, "# Comment \n No Comment", sizeof(str));
  3646. tt_str_op("No Comment",OP_EQ, eat_whitespace(str));
  3647. tt_str_op("No Comment",OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
  3648. tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
  3649. tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3650. /* Eat comment & ws mix */
  3651. strlcpy(str, " # \t Comment \n\t\nNo Comment", sizeof(str));
  3652. tt_str_op("No Comment",OP_EQ, eat_whitespace(str));
  3653. tt_str_op("No Comment",OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
  3654. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_no_nl(str));
  3655. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3656. /* Eat entire comment */
  3657. strlcpy(str, "#Comment", sizeof(str));
  3658. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
  3659. tt_ptr_op(str + strlen(str),OP_EQ,
  3660. eat_whitespace_eos(str, str + strlen(str)));
  3661. tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
  3662. tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3663. /* Blank line, then comment */
  3664. strlcpy(str, " \t\n # Comment", sizeof(str));
  3665. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
  3666. tt_ptr_op(str + strlen(str),OP_EQ,
  3667. eat_whitespace_eos(str, str + strlen(str)));
  3668. tt_ptr_op(str + 2,OP_EQ, eat_whitespace_no_nl(str));
  3669. tt_ptr_op(str + 2,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3670. done:
  3671. ;
  3672. }
  3673. /** Return a newly allocated smartlist containing the lines of text in
  3674. * <b>lines</b>. The returned strings are heap-allocated, and must be
  3675. * freed by the caller.
  3676. *
  3677. * XXXX? Move to container.[hc] ? */
  3678. static smartlist_t *
  3679. smartlist_new_from_text_lines(const char *lines)
  3680. {
  3681. smartlist_t *sl = smartlist_new();
  3682. char *last_line;
  3683. smartlist_split_string(sl, lines, "\n", 0, 0);
  3684. last_line = smartlist_pop_last(sl);
  3685. if (last_line != NULL && *last_line != '\0') {
  3686. smartlist_add(sl, last_line);
  3687. } else {
  3688. tor_free(last_line);
  3689. }
  3690. return sl;
  3691. }
  3692. /** Test smartlist_new_from_text_lines */
  3693. static void
  3694. test_util_sl_new_from_text_lines(void *ptr)
  3695. {
  3696. (void)ptr;
  3697. { /* Normal usage */
  3698. smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz\n");
  3699. int sl_len = smartlist_len(sl);
  3700. tt_want_int_op(sl_len, OP_EQ, 3);
  3701. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
  3702. if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), OP_EQ, "bar");
  3703. if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), OP_EQ, "baz");
  3704. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  3705. smartlist_free(sl);
  3706. }
  3707. { /* No final newline */
  3708. smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz");
  3709. int sl_len = smartlist_len(sl);
  3710. tt_want_int_op(sl_len, OP_EQ, 3);
  3711. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
  3712. if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), OP_EQ, "bar");
  3713. if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), OP_EQ, "baz");
  3714. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  3715. smartlist_free(sl);
  3716. }
  3717. { /* No newlines */
  3718. smartlist_t *sl = smartlist_new_from_text_lines("foo");
  3719. int sl_len = smartlist_len(sl);
  3720. tt_want_int_op(sl_len, OP_EQ, 1);
  3721. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
  3722. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  3723. smartlist_free(sl);
  3724. }
  3725. { /* No text at all */
  3726. smartlist_t *sl = smartlist_new_from_text_lines("");
  3727. int sl_len = smartlist_len(sl);
  3728. tt_want_int_op(sl_len, OP_EQ, 0);
  3729. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  3730. smartlist_free(sl);
  3731. }
  3732. }
  3733. static void
  3734. test_util_envnames(void *ptr)
  3735. {
  3736. (void) ptr;
  3737. tt_assert(environment_variable_names_equal("abc", "abc"));
  3738. tt_assert(environment_variable_names_equal("abc", "abc="));
  3739. tt_assert(environment_variable_names_equal("abc", "abc=def"));
  3740. tt_assert(environment_variable_names_equal("abc=def", "abc"));
  3741. tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
  3742. tt_assert(environment_variable_names_equal("abc", "abc"));
  3743. tt_assert(environment_variable_names_equal("abc", "abc="));
  3744. tt_assert(environment_variable_names_equal("abc", "abc=def"));
  3745. tt_assert(environment_variable_names_equal("abc=def", "abc"));
  3746. tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
  3747. tt_assert(!environment_variable_names_equal("abc", "abcd"));
  3748. tt_assert(!environment_variable_names_equal("abc=", "abcd"));
  3749. tt_assert(!environment_variable_names_equal("abc=", "abcd"));
  3750. tt_assert(!environment_variable_names_equal("abc=", "def"));
  3751. tt_assert(!environment_variable_names_equal("abc=", "def="));
  3752. tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
  3753. tt_assert(!environment_variable_names_equal("", "a=def"));
  3754. /* A bit surprising. */
  3755. tt_assert(environment_variable_names_equal("", "=def"));
  3756. tt_assert(environment_variable_names_equal("=y", "=x"));
  3757. done:
  3758. ;
  3759. }
  3760. /** Test process_environment_make */
  3761. static void
  3762. test_util_make_environment(void *ptr)
  3763. {
  3764. const char *env_vars_string =
  3765. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  3766. "HOME=/home/foozer\n";
  3767. const char expected_windows_env_block[] =
  3768. "HOME=/home/foozer\000"
  3769. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
  3770. "\000";
  3771. size_t expected_windows_env_block_len =
  3772. sizeof(expected_windows_env_block) - 1;
  3773. smartlist_t *env_vars = smartlist_new_from_text_lines(env_vars_string);
  3774. smartlist_t *env_vars_sorted = smartlist_new();
  3775. smartlist_t *env_vars_in_unixoid_env_block_sorted = smartlist_new();
  3776. process_environment_t *env;
  3777. (void)ptr;
  3778. env = process_environment_make(env_vars);
  3779. /* Check that the Windows environment block is correct. */
  3780. tt_want(tor_memeq(expected_windows_env_block, env->windows_environment_block,
  3781. expected_windows_env_block_len));
  3782. /* Now for the Unixoid environment block. We don't care which order
  3783. * these environment variables are in, so we sort both lists first. */
  3784. smartlist_add_all(env_vars_sorted, env_vars);
  3785. {
  3786. char **v;
  3787. for (v = env->unixoid_environment_block; *v; ++v) {
  3788. smartlist_add(env_vars_in_unixoid_env_block_sorted, *v);
  3789. }
  3790. }
  3791. smartlist_sort_strings(env_vars_sorted);
  3792. smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted);
  3793. tt_want_int_op(smartlist_len(env_vars_sorted), OP_EQ,
  3794. smartlist_len(env_vars_in_unixoid_env_block_sorted));
  3795. {
  3796. int len = smartlist_len(env_vars_sorted);
  3797. int i;
  3798. if (smartlist_len(env_vars_in_unixoid_env_block_sorted) < len) {
  3799. len = smartlist_len(env_vars_in_unixoid_env_block_sorted);
  3800. }
  3801. for (i = 0; i < len; ++i) {
  3802. tt_want_str_op(smartlist_get(env_vars_sorted, i), OP_EQ,
  3803. smartlist_get(env_vars_in_unixoid_env_block_sorted, i));
  3804. }
  3805. }
  3806. /* Clean up. */
  3807. smartlist_free(env_vars_in_unixoid_env_block_sorted);
  3808. smartlist_free(env_vars_sorted);
  3809. SMARTLIST_FOREACH(env_vars, char *, x, tor_free(x));
  3810. smartlist_free(env_vars);
  3811. process_environment_free(env);
  3812. }
  3813. /** Test set_environment_variable_in_smartlist */
  3814. static void
  3815. test_util_set_env_var_in_sl(void *ptr)
  3816. {
  3817. /* The environment variables in these strings are in arbitrary
  3818. * order; we sort the resulting lists before comparing them.
  3819. *
  3820. * (They *will not* end up in the order shown in
  3821. * expected_resulting_env_vars_string.) */
  3822. const char *base_env_vars_string =
  3823. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  3824. "HOME=/home/foozer\n"
  3825. "TERM=xterm\n"
  3826. "SHELL=/bin/ksh\n"
  3827. "USER=foozer\n"
  3828. "LOGNAME=foozer\n"
  3829. "USERNAME=foozer\n"
  3830. "LANG=en_US.utf8\n"
  3831. ;
  3832. const char *new_env_vars_string =
  3833. "TERM=putty\n"
  3834. "DISPLAY=:18.0\n"
  3835. ;
  3836. const char *expected_resulting_env_vars_string =
  3837. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  3838. "HOME=/home/foozer\n"
  3839. "TERM=putty\n"
  3840. "SHELL=/bin/ksh\n"
  3841. "USER=foozer\n"
  3842. "LOGNAME=foozer\n"
  3843. "USERNAME=foozer\n"
  3844. "LANG=en_US.utf8\n"
  3845. "DISPLAY=:18.0\n"
  3846. ;
  3847. smartlist_t *merged_env_vars =
  3848. smartlist_new_from_text_lines(base_env_vars_string);
  3849. smartlist_t *new_env_vars =
  3850. smartlist_new_from_text_lines(new_env_vars_string);
  3851. smartlist_t *expected_resulting_env_vars =
  3852. smartlist_new_from_text_lines(expected_resulting_env_vars_string);
  3853. /* Elements of merged_env_vars are heap-allocated, and must be
  3854. * freed. Some of them are (or should) be freed by
  3855. * set_environment_variable_in_smartlist.
  3856. *
  3857. * Elements of new_env_vars are heap-allocated, but are copied into
  3858. * merged_env_vars, so they are not freed separately at the end of
  3859. * the function.
  3860. *
  3861. * Elements of expected_resulting_env_vars are heap-allocated, and
  3862. * must be freed. */
  3863. (void)ptr;
  3864. SMARTLIST_FOREACH(new_env_vars, char *, env_var,
  3865. set_environment_variable_in_smartlist(merged_env_vars,
  3866. env_var,
  3867. tor_free_,
  3868. 1));
  3869. smartlist_sort_strings(merged_env_vars);
  3870. smartlist_sort_strings(expected_resulting_env_vars);
  3871. tt_want_int_op(smartlist_len(merged_env_vars), OP_EQ,
  3872. smartlist_len(expected_resulting_env_vars));
  3873. {
  3874. int len = smartlist_len(merged_env_vars);
  3875. int i;
  3876. if (smartlist_len(expected_resulting_env_vars) < len) {
  3877. len = smartlist_len(expected_resulting_env_vars);
  3878. }
  3879. for (i = 0; i < len; ++i) {
  3880. tt_want_str_op(smartlist_get(merged_env_vars, i), OP_EQ,
  3881. smartlist_get(expected_resulting_env_vars, i));
  3882. }
  3883. }
  3884. /* Clean up. */
  3885. SMARTLIST_FOREACH(merged_env_vars, char *, x, tor_free(x));
  3886. smartlist_free(merged_env_vars);
  3887. smartlist_free(new_env_vars);
  3888. SMARTLIST_FOREACH(expected_resulting_env_vars, char *, x, tor_free(x));
  3889. smartlist_free(expected_resulting_env_vars);
  3890. }
  3891. static void
  3892. test_util_weak_random(void *arg)
  3893. {
  3894. int i, j, n[16];
  3895. tor_weak_rng_t rng;
  3896. (void) arg;
  3897. tor_init_weak_random(&rng, (unsigned)time(NULL));
  3898. for (i = 1; i <= 256; ++i) {
  3899. for (j=0;j<100;++j) {
  3900. int r = tor_weak_random_range(&rng, i);
  3901. tt_int_op(0, OP_LE, r);
  3902. tt_int_op(r, OP_LT, i);
  3903. }
  3904. }
  3905. memset(n,0,sizeof(n));
  3906. for (j=0;j<8192;++j) {
  3907. n[tor_weak_random_range(&rng, 16)]++;
  3908. }
  3909. for (i=0;i<16;++i)
  3910. tt_int_op(n[i], OP_GT, 0);
  3911. done:
  3912. ;
  3913. }
  3914. static void
  3915. test_util_mathlog(void *arg)
  3916. {
  3917. double d;
  3918. (void) arg;
  3919. d = tor_mathlog(2.718281828);
  3920. tt_double_op(fabs(d - 1.0), OP_LT, .000001);
  3921. d = tor_mathlog(10);
  3922. tt_double_op(fabs(d - 2.30258509), OP_LT, .000001);
  3923. done:
  3924. ;
  3925. }
  3926. static void
  3927. test_util_round_to_next_multiple_of(void *arg)
  3928. {
  3929. (void)arg;
  3930. tt_assert(round_uint64_to_next_multiple_of(0,1) == 0);
  3931. tt_assert(round_uint64_to_next_multiple_of(0,7) == 0);
  3932. tt_assert(round_uint64_to_next_multiple_of(99,1) == 99);
  3933. tt_assert(round_uint64_to_next_multiple_of(99,7) == 105);
  3934. tt_assert(round_uint64_to_next_multiple_of(99,9) == 99);
  3935. tt_assert(round_int64_to_next_multiple_of(0,1) == 0);
  3936. tt_assert(round_int64_to_next_multiple_of(0,7) == 0);
  3937. tt_assert(round_int64_to_next_multiple_of(99,1) == 99);
  3938. tt_assert(round_int64_to_next_multiple_of(99,7) == 105);
  3939. tt_assert(round_int64_to_next_multiple_of(99,9) == 99);
  3940. tt_assert(round_int64_to_next_multiple_of(-99,1) == -99);
  3941. tt_assert(round_int64_to_next_multiple_of(-99,7) == -98);
  3942. tt_assert(round_int64_to_next_multiple_of(-99,9) == -99);
  3943. tt_assert(round_int64_to_next_multiple_of(INT64_MIN,2) == INT64_MIN);
  3944. tt_assert(round_int64_to_next_multiple_of(INT64_MAX,2) ==
  3945. INT64_MAX-INT64_MAX%2);
  3946. done:
  3947. ;
  3948. }
  3949. static void
  3950. test_util_laplace(void *arg)
  3951. {
  3952. /* Sample values produced using Python's SciPy:
  3953. *
  3954. * >>> from scipy.stats import laplace
  3955. * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
  3956. ... loc = 24, scale = 24)
  3957. * array([ nan, -inf, -69.88855213, 24. ,
  3958. * 24.48486498, 117.88855213, inf, nan])
  3959. */
  3960. const double mu = 24.0, b = 24.0;
  3961. const double delta_f = 15.0, epsilon = 0.3; /* b = 15.0 / 0.3 = 50.0 */
  3962. (void)arg;
  3963. tt_assert(isinf(sample_laplace_distribution(mu, b, 0.0)));
  3964. test_feq(-69.88855213, sample_laplace_distribution(mu, b, 0.01));
  3965. test_feq(24.0, sample_laplace_distribution(mu, b, 0.5));
  3966. test_feq(24.48486498, sample_laplace_distribution(mu, b, 0.51));
  3967. test_feq(117.88855213, sample_laplace_distribution(mu, b, 0.99));
  3968. /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
  3969. * ... loc = 0, scale = 50)
  3970. * array([ -inf, -80.47189562, -34.65735903, 0. ,
  3971. * 34.65735903, 80.47189562, 195.60115027])
  3972. */
  3973. tt_assert(INT64_MIN + 20 ==
  3974. add_laplace_noise(20, 0.0, delta_f, epsilon));
  3975. tt_assert(-60 == add_laplace_noise(20, 0.1, delta_f, epsilon));
  3976. tt_assert(-14 == add_laplace_noise(20, 0.25, delta_f, epsilon));
  3977. tt_assert(20 == add_laplace_noise(20, 0.5, delta_f, epsilon));
  3978. tt_assert(54 == add_laplace_noise(20, 0.75, delta_f, epsilon));
  3979. tt_assert(100 == add_laplace_noise(20, 0.9, delta_f, epsilon));
  3980. tt_assert(215 == add_laplace_noise(20, 0.99, delta_f, epsilon));
  3981. done:
  3982. ;
  3983. }
  3984. static void
  3985. test_util_strclear(void *arg)
  3986. {
  3987. static const char *vals[] = { "", "a", "abcdef", "abcdefgh", NULL };
  3988. int i;
  3989. char *v = NULL;
  3990. (void)arg;
  3991. for (i = 0; vals[i]; ++i) {
  3992. size_t n;
  3993. v = tor_strdup(vals[i]);
  3994. n = strlen(v);
  3995. tor_strclear(v);
  3996. tt_assert(tor_mem_is_zero(v, n+1));
  3997. tor_free(v);
  3998. }
  3999. done:
  4000. tor_free(v);
  4001. }
  4002. #define UTIL_LEGACY(name) \
  4003. { #name, test_util_ ## name , 0, NULL, NULL }
  4004. #define UTIL_TEST(name, flags) \
  4005. { #name, test_util_ ## name, flags, NULL, NULL }
  4006. #ifdef FD_CLOEXEC
  4007. #define CAN_CHECK_CLOEXEC
  4008. static int
  4009. fd_is_cloexec(tor_socket_t fd)
  4010. {
  4011. int flags = fcntl(fd, F_GETFD, 0);
  4012. return (flags & FD_CLOEXEC) == FD_CLOEXEC;
  4013. }
  4014. #endif
  4015. #ifndef _WIN32
  4016. #define CAN_CHECK_NONBLOCK
  4017. static int
  4018. fd_is_nonblocking(tor_socket_t fd)
  4019. {
  4020. int flags = fcntl(fd, F_GETFL, 0);
  4021. return (flags & O_NONBLOCK) == O_NONBLOCK;
  4022. }
  4023. #endif
  4024. static void
  4025. test_util_socket(void *arg)
  4026. {
  4027. tor_socket_t fd1 = TOR_INVALID_SOCKET;
  4028. tor_socket_t fd2 = TOR_INVALID_SOCKET;
  4029. tor_socket_t fd3 = TOR_INVALID_SOCKET;
  4030. tor_socket_t fd4 = TOR_INVALID_SOCKET;
  4031. int n = get_n_open_sockets();
  4032. TT_BLATHER(("Starting with %d open sockets.", n));
  4033. (void)arg;
  4034. fd1 = tor_open_socket_with_extensions(AF_INET, SOCK_STREAM, 0, 0, 0);
  4035. fd2 = tor_open_socket_with_extensions(AF_INET, SOCK_STREAM, 0, 0, 1);
  4036. tt_assert(SOCKET_OK(fd1));
  4037. tt_assert(SOCKET_OK(fd2));
  4038. tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
  4039. //fd3 = tor_open_socket_with_extensions(AF_INET, SOCK_STREAM, 0, 1, 0);
  4040. //fd4 = tor_open_socket_with_extensions(AF_INET, SOCK_STREAM, 0, 1, 1);
  4041. fd3 = tor_open_socket(AF_INET, SOCK_STREAM, 0);
  4042. fd4 = tor_open_socket_nonblocking(AF_INET, SOCK_STREAM, 0);
  4043. tt_assert(SOCKET_OK(fd3));
  4044. tt_assert(SOCKET_OK(fd4));
  4045. tt_int_op(get_n_open_sockets(), OP_EQ, n + 4);
  4046. #ifdef CAN_CHECK_CLOEXEC
  4047. tt_int_op(fd_is_cloexec(fd1), OP_EQ, 0);
  4048. tt_int_op(fd_is_cloexec(fd2), OP_EQ, 0);
  4049. tt_int_op(fd_is_cloexec(fd3), OP_EQ, 1);
  4050. tt_int_op(fd_is_cloexec(fd4), OP_EQ, 1);
  4051. #endif
  4052. #ifdef CAN_CHECK_NONBLOCK
  4053. tt_int_op(fd_is_nonblocking(fd1), OP_EQ, 0);
  4054. tt_int_op(fd_is_nonblocking(fd2), OP_EQ, 1);
  4055. tt_int_op(fd_is_nonblocking(fd3), OP_EQ, 0);
  4056. tt_int_op(fd_is_nonblocking(fd4), OP_EQ, 1);
  4057. #endif
  4058. tor_close_socket(fd1);
  4059. tor_close_socket(fd2);
  4060. fd1 = fd2 = TOR_INVALID_SOCKET;
  4061. tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
  4062. tor_close_socket(fd3);
  4063. tor_close_socket(fd4);
  4064. fd3 = fd4 = TOR_INVALID_SOCKET;
  4065. tt_int_op(get_n_open_sockets(), OP_EQ, n);
  4066. done:
  4067. if (SOCKET_OK(fd1))
  4068. tor_close_socket(fd1);
  4069. if (SOCKET_OK(fd2))
  4070. tor_close_socket(fd2);
  4071. if (SOCKET_OK(fd3))
  4072. tor_close_socket(fd3);
  4073. if (SOCKET_OK(fd4))
  4074. tor_close_socket(fd4);
  4075. }
  4076. static void *
  4077. socketpair_test_setup(const struct testcase_t *testcase)
  4078. {
  4079. return testcase->setup_data;
  4080. }
  4081. static int
  4082. socketpair_test_cleanup(const struct testcase_t *testcase, void *ptr)
  4083. {
  4084. (void)testcase;
  4085. (void)ptr;
  4086. return 1;
  4087. }
  4088. static const struct testcase_setup_t socketpair_setup = {
  4089. socketpair_test_setup, socketpair_test_cleanup
  4090. };
  4091. /* Test for socketpair and ersatz_socketpair(). We test them both, since
  4092. * the latter is a tolerably good way to exersize tor_accept_socket(). */
  4093. static void
  4094. test_util_socketpair(void *arg)
  4095. {
  4096. const int ersatz = !strcmp(arg, "1");
  4097. int (*const tor_socketpair_fn)(int, int, int, tor_socket_t[2]) =
  4098. ersatz ? tor_ersatz_socketpair : tor_socketpair;
  4099. int n = get_n_open_sockets();
  4100. tor_socket_t fds[2] = {TOR_INVALID_SOCKET, TOR_INVALID_SOCKET};
  4101. const int family = AF_UNIX;
  4102. tt_int_op(0, OP_EQ, tor_socketpair_fn(family, SOCK_STREAM, 0, fds));
  4103. tt_assert(SOCKET_OK(fds[0]));
  4104. tt_assert(SOCKET_OK(fds[1]));
  4105. tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
  4106. #ifdef CAN_CHECK_CLOEXEC
  4107. tt_int_op(fd_is_cloexec(fds[0]), OP_EQ, 1);
  4108. tt_int_op(fd_is_cloexec(fds[1]), OP_EQ, 1);
  4109. #endif
  4110. #ifdef CAN_CHECK_NONBLOCK
  4111. tt_int_op(fd_is_nonblocking(fds[0]), OP_EQ, 0);
  4112. tt_int_op(fd_is_nonblocking(fds[1]), OP_EQ, 0);
  4113. #endif
  4114. done:
  4115. if (SOCKET_OK(fds[0]))
  4116. tor_close_socket(fds[0]);
  4117. if (SOCKET_OK(fds[1]))
  4118. tor_close_socket(fds[1]);
  4119. }
  4120. static void
  4121. test_util_max_mem(void *arg)
  4122. {
  4123. size_t memory1, memory2;
  4124. int r, r2;
  4125. (void) arg;
  4126. r = get_total_system_memory(&memory1);
  4127. r2 = get_total_system_memory(&memory2);
  4128. tt_int_op(r, OP_EQ, r2);
  4129. tt_uint_op(memory2, OP_EQ, memory1);
  4130. TT_BLATHER(("System memory: "U64_FORMAT, U64_PRINTF_ARG(memory1)));
  4131. if (r==0) {
  4132. /* You have at least a megabyte. */
  4133. tt_uint_op(memory1, OP_GT, (1<<20));
  4134. } else {
  4135. /* You do not have a petabyte. */
  4136. #if SIZEOF_SIZE_T == SIZEOF_UINT64_T
  4137. tt_u64_op(memory1, OP_LT, (U64_LITERAL(1)<<50));
  4138. #endif
  4139. }
  4140. done:
  4141. ;
  4142. }
  4143. static void
  4144. test_util_hostname_validation(void *arg)
  4145. {
  4146. (void)arg;
  4147. // Lets try valid hostnames first.
  4148. tt_assert(string_is_valid_hostname("torproject.org"));
  4149. tt_assert(string_is_valid_hostname("ocw.mit.edu"));
  4150. tt_assert(string_is_valid_hostname("i.4cdn.org"));
  4151. tt_assert(string_is_valid_hostname("stanford.edu"));
  4152. tt_assert(string_is_valid_hostname("multiple-words-with-hypens.jp"));
  4153. // Subdomain name cannot start with '-'.
  4154. tt_assert(!string_is_valid_hostname("-torproject.org"));
  4155. tt_assert(!string_is_valid_hostname("subdomain.-domain.org"));
  4156. tt_assert(!string_is_valid_hostname("-subdomain.domain.org"));
  4157. // Hostnames cannot contain non-alphanumeric characters.
  4158. tt_assert(!string_is_valid_hostname("%%domain.\\org."));
  4159. tt_assert(!string_is_valid_hostname("***x.net"));
  4160. tt_assert(!string_is_valid_hostname("___abc.org"));
  4161. tt_assert(!string_is_valid_hostname("\xff\xffxyz.org"));
  4162. tt_assert(!string_is_valid_hostname("word1 word2.net"));
  4163. // XXX: do we allow single-label DNS names?
  4164. done:
  4165. return;
  4166. }
  4167. static void
  4168. test_util_ipv4_validation(void *arg)
  4169. {
  4170. (void)arg;
  4171. tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
  4172. tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
  4173. tt_assert(!string_is_valid_ipv4_address("abcd"));
  4174. tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
  4175. tt_assert(!string_is_valid_ipv4_address("8.8."));
  4176. done:
  4177. return;
  4178. }
  4179. struct testcase_t util_tests[] = {
  4180. UTIL_LEGACY(time),
  4181. UTIL_TEST(parse_http_time, 0),
  4182. UTIL_LEGACY(config_line),
  4183. UTIL_LEGACY(config_line_quotes),
  4184. UTIL_LEGACY(config_line_comment_character),
  4185. UTIL_LEGACY(config_line_escaped_content),
  4186. #ifndef _WIN32
  4187. UTIL_LEGACY(expand_filename),
  4188. #endif
  4189. UTIL_LEGACY(escape_string_socks),
  4190. UTIL_LEGACY(string_is_key_value),
  4191. UTIL_LEGACY(strmisc),
  4192. UTIL_LEGACY(pow2),
  4193. UTIL_LEGACY(gzip),
  4194. UTIL_LEGACY(datadir),
  4195. #ifdef ENABLE_MEMPOOLS
  4196. UTIL_LEGACY(mempool),
  4197. #endif
  4198. UTIL_LEGACY(memarea),
  4199. UTIL_LEGACY(control_formats),
  4200. UTIL_LEGACY(mmap),
  4201. UTIL_LEGACY(threads),
  4202. UTIL_LEGACY(sscanf),
  4203. UTIL_LEGACY(format_time_interval),
  4204. UTIL_LEGACY(path_is_relative),
  4205. UTIL_LEGACY(strtok),
  4206. UTIL_LEGACY(di_ops),
  4207. UTIL_TEST(round_to_next_multiple_of, 0),
  4208. UTIL_TEST(laplace, 0),
  4209. UTIL_TEST(strclear, 0),
  4210. UTIL_TEST(find_str_at_start_of_line, 0),
  4211. UTIL_TEST(string_is_C_identifier, 0),
  4212. UTIL_TEST(asprintf, 0),
  4213. UTIL_TEST(listdir, 0),
  4214. UTIL_TEST(parent_dir, 0),
  4215. UTIL_TEST(ftruncate, 0),
  4216. #ifdef _WIN32
  4217. UTIL_TEST(load_win_lib, 0),
  4218. #endif
  4219. #ifndef _WIN32
  4220. UTIL_TEST(exit_status, 0),
  4221. UTIL_TEST(fgets_eagain, 0),
  4222. #endif
  4223. UTIL_TEST(spawn_background_ok, 0),
  4224. UTIL_TEST(spawn_background_fail, 0),
  4225. UTIL_TEST(spawn_background_partial_read, 0),
  4226. UTIL_TEST(spawn_background_exit_early, 0),
  4227. UTIL_TEST(spawn_background_waitpid_notify, 0),
  4228. UTIL_TEST(format_hex_number, 0),
  4229. UTIL_TEST(format_dec_number, 0),
  4230. UTIL_TEST(join_win_cmdline, 0),
  4231. UTIL_TEST(split_lines, 0),
  4232. UTIL_TEST(n_bits_set, 0),
  4233. UTIL_TEST(eat_whitespace, 0),
  4234. UTIL_TEST(sl_new_from_text_lines, 0),
  4235. UTIL_TEST(envnames, 0),
  4236. UTIL_TEST(make_environment, 0),
  4237. UTIL_TEST(set_env_var_in_sl, 0),
  4238. UTIL_TEST(read_file_eof_tiny_limit, 0),
  4239. UTIL_TEST(read_file_eof_one_loop_a, 0),
  4240. UTIL_TEST(read_file_eof_one_loop_b, 0),
  4241. UTIL_TEST(read_file_eof_two_loops, 0),
  4242. UTIL_TEST(read_file_eof_two_loops_b, 0),
  4243. UTIL_TEST(read_file_eof_zero_bytes, 0),
  4244. UTIL_TEST(write_chunks_to_file, 0),
  4245. UTIL_TEST(mathlog, 0),
  4246. UTIL_TEST(weak_random, 0),
  4247. UTIL_TEST(socket, TT_FORK),
  4248. { "socketpair", test_util_socketpair, TT_FORK, &socketpair_setup,
  4249. (void*)"0" },
  4250. { "socketpair_ersatz", test_util_socketpair, TT_FORK,
  4251. &socketpair_setup, (void*)"1" },
  4252. UTIL_TEST(max_mem, 0),
  4253. UTIL_TEST(hostname_validation, 0),
  4254. UTIL_TEST(ipv4_validation, 0),
  4255. END_OF_TESTCASES
  4256. };