test_util.c 87 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2011, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #define CONTROL_PRIVATE
  7. #define MEMPOOL_PRIVATE
  8. #define UTIL_PRIVATE
  9. #include "or.h"
  10. #include "config.h"
  11. #include "control.h"
  12. #include "test.h"
  13. #include "mempool.h"
  14. #include "memarea.h"
  15. static void
  16. test_util_time(void)
  17. {
  18. struct timeval start, end;
  19. struct tm a_time;
  20. char timestr[128];
  21. time_t t_res;
  22. int i;
  23. struct timeval tv;
  24. /* Test tv_udiff */
  25. start.tv_sec = 5;
  26. start.tv_usec = 5000;
  27. end.tv_sec = 5;
  28. end.tv_usec = 5000;
  29. test_eq(0L, tv_udiff(&start, &end));
  30. end.tv_usec = 7000;
  31. test_eq(2000L, tv_udiff(&start, &end));
  32. end.tv_sec = 6;
  33. test_eq(1002000L, tv_udiff(&start, &end));
  34. end.tv_usec = 0;
  35. test_eq(995000L, tv_udiff(&start, &end));
  36. end.tv_sec = 4;
  37. test_eq(-1005000L, tv_udiff(&start, &end));
  38. /* Test tor_timegm */
  39. /* The test values here are confirmed to be correct on a platform
  40. * with a working timegm. */
  41. a_time.tm_year = 2003-1900;
  42. a_time.tm_mon = 7;
  43. a_time.tm_mday = 30;
  44. a_time.tm_hour = 6;
  45. a_time.tm_min = 14;
  46. a_time.tm_sec = 55;
  47. test_eq((time_t) 1062224095UL, tor_timegm(&a_time));
  48. a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
  49. test_eq((time_t) 1093846495UL, tor_timegm(&a_time));
  50. a_time.tm_mon = 1; /* Try a leap year, in feb. */
  51. a_time.tm_mday = 10;
  52. test_eq((time_t) 1076393695UL, tor_timegm(&a_time));
  53. a_time.tm_mon = 0;
  54. a_time.tm_mday = 10;
  55. test_eq((time_t) 1073715295UL, tor_timegm(&a_time));
  56. a_time.tm_mon = 12; /* Wrong month, it's 0-based */
  57. a_time.tm_mday = 10;
  58. test_eq((time_t) -1, tor_timegm(&a_time));
  59. a_time.tm_mon = -1; /* Wrong month */
  60. a_time.tm_mday = 10;
  61. test_eq((time_t) -1, tor_timegm(&a_time));
  62. /* Test {format,parse}_rfc1123_time */
  63. format_rfc1123_time(timestr, 0);
  64. test_streq("Thu, 01 Jan 1970 00:00:00 GMT", timestr);
  65. format_rfc1123_time(timestr, (time_t)1091580502UL);
  66. test_streq("Wed, 04 Aug 2004 00:48:22 GMT", timestr);
  67. t_res = 0;
  68. i = parse_rfc1123_time(timestr, &t_res);
  69. test_eq(0,i);
  70. test_eq(t_res, (time_t)1091580502UL);
  71. /* The timezone doesn't matter */
  72. t_res = 0;
  73. test_eq(0, parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res));
  74. test_eq(t_res, (time_t)1091580502UL);
  75. test_eq(-1, parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
  76. test_eq(-1, parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res));
  77. test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res));
  78. test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res));
  79. test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res));
  80. test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res));
  81. test_eq(-1, parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res));
  82. test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res));
  83. #if 0
  84. /* This fails, I imagine it's important and should be fixed? */
  85. test_eq(-1, parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res));
  86. /* Why is this string valid (ie. the test fails because it doesn't
  87. return -1)? */
  88. test_eq(-1, parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res));
  89. #endif
  90. /* Test parse_iso_time */
  91. t_res = 0;
  92. i = parse_iso_time("", &t_res);
  93. test_eq(-1, i);
  94. t_res = 0;
  95. i = parse_iso_time("2004-08-32 00:48:22", &t_res);
  96. test_eq(-1, i);
  97. t_res = 0;
  98. i = parse_iso_time("1969-08-03 00:48:22", &t_res);
  99. test_eq(-1, i);
  100. t_res = 0;
  101. i = parse_iso_time("2004-08-04 00:48:22", &t_res);
  102. test_eq(0,i);
  103. test_eq(t_res, (time_t)1091580502UL);
  104. t_res = 0;
  105. i = parse_iso_time("2004-8-4 0:48:22", &t_res);
  106. test_eq(0, i);
  107. test_eq(t_res, (time_t)1091580502UL);
  108. test_eq(-1, parse_iso_time("2004-08-zz 99-99x99 GMT", &t_res));
  109. test_eq(-1, parse_iso_time("2011-03-32 00:00:00 GMT", &t_res));
  110. test_eq(-1, parse_iso_time("2011-03-30 24:00:00 GMT", &t_res));
  111. test_eq(-1, parse_iso_time("2011-03-30 23:60:00 GMT", &t_res));
  112. test_eq(-1, parse_iso_time("2011-03-30 23:59:62 GMT", &t_res));
  113. test_eq(-1, parse_iso_time("1969-03-30 23:59:59 GMT", &t_res));
  114. test_eq(-1, parse_iso_time("2011-00-30 23:59:59 GMT", &t_res));
  115. test_eq(-1, parse_iso_time("2011-03-30 23:59", &t_res));
  116. /* Test tor_gettimeofday */
  117. end.tv_sec = 4;
  118. end.tv_usec = 999990;
  119. start.tv_sec = 1;
  120. start.tv_usec = 500;
  121. tor_gettimeofday(&start);
  122. /* now make sure time works. */
  123. tor_gettimeofday(&end);
  124. /* We might've timewarped a little. */
  125. tt_int_op(tv_udiff(&start, &end), >=, -5000);
  126. /* Test format_iso_time */
  127. tv.tv_sec = (time_t)1326296338;
  128. tv.tv_usec = 3060;
  129. format_iso_time(timestr, tv.tv_sec);
  130. test_streq("2012-01-11 15:38:58", timestr);
  131. /* The output of format_local_iso_time will vary by timezone, and setting
  132. our timezone for testing purposes would be a nontrivial flaky pain.
  133. Skip this test for now.
  134. format_local_iso_time(timestr, tv.tv_sec);
  135. test_streq("2012-01-11 10:38:58", timestr);
  136. */
  137. format_iso_time_nospace(timestr, tv.tv_sec);
  138. test_streq("2012-01-11T15:38:58", timestr);
  139. test_eq(strlen(timestr), ISO_TIME_LEN);
  140. format_iso_time_nospace_usec(timestr, &tv);
  141. test_streq("2012-01-11T15:38:58.003060", timestr);
  142. test_eq(strlen(timestr), ISO_TIME_USEC_LEN);
  143. done:
  144. ;
  145. }
  146. static void
  147. test_util_config_line(void)
  148. {
  149. char buf[1024];
  150. char *k=NULL, *v=NULL;
  151. const char *str;
  152. /* Test parse_config_line_from_str */
  153. strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n"
  154. "k2\n"
  155. "k3 \n" "\n" " \n" "#comment\n"
  156. "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
  157. "kseven \"a quoted 'string\"\n"
  158. "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
  159. "k9 a line that\\\n spans two lines.\n\n"
  160. "k10 more than\\\n one contin\\\nuation\n"
  161. "k11 \\\ncontinuation at the start\n"
  162. "k12 line with a\\\n#comment\n embedded\n"
  163. "k13\\\ncontinuation at the very start\n"
  164. "k14 a line that has a comment and # ends with a slash \\\n"
  165. "k15 this should be the next new line\n"
  166. "k16 a line that has a comment and # ends without a slash \n"
  167. "k17 this should be the next new line\n"
  168. , sizeof(buf));
  169. str = buf;
  170. str = parse_config_line_from_str(str, &k, &v);
  171. test_streq(k, "k");
  172. test_streq(v, "v");
  173. tor_free(k); tor_free(v);
  174. test_assert(!strcmpstart(str, "key value with"));
  175. str = parse_config_line_from_str(str, &k, &v);
  176. test_streq(k, "key");
  177. test_streq(v, "value with spaces");
  178. tor_free(k); tor_free(v);
  179. test_assert(!strcmpstart(str, "keykey"));
  180. str = parse_config_line_from_str(str, &k, &v);
  181. test_streq(k, "keykey");
  182. test_streq(v, "val");
  183. tor_free(k); tor_free(v);
  184. test_assert(!strcmpstart(str, "k2\n"));
  185. str = parse_config_line_from_str(str, &k, &v);
  186. test_streq(k, "k2");
  187. test_streq(v, "");
  188. tor_free(k); tor_free(v);
  189. test_assert(!strcmpstart(str, "k3 \n"));
  190. str = parse_config_line_from_str(str, &k, &v);
  191. test_streq(k, "k3");
  192. test_streq(v, "");
  193. tor_free(k); tor_free(v);
  194. test_assert(!strcmpstart(str, "#comment"));
  195. str = parse_config_line_from_str(str, &k, &v);
  196. test_streq(k, "k4");
  197. test_streq(v, "");
  198. tor_free(k); tor_free(v);
  199. test_assert(!strcmpstart(str, "k5#abc"));
  200. str = parse_config_line_from_str(str, &k, &v);
  201. test_streq(k, "k5");
  202. test_streq(v, "");
  203. tor_free(k); tor_free(v);
  204. test_assert(!strcmpstart(str, "k6"));
  205. str = parse_config_line_from_str(str, &k, &v);
  206. test_streq(k, "k6");
  207. test_streq(v, "val");
  208. tor_free(k); tor_free(v);
  209. test_assert(!strcmpstart(str, "kseven"));
  210. str = parse_config_line_from_str(str, &k, &v);
  211. test_streq(k, "kseven");
  212. test_streq(v, "a quoted \'string");
  213. tor_free(k); tor_free(v);
  214. test_assert(!strcmpstart(str, "k8 "));
  215. str = parse_config_line_from_str(str, &k, &v);
  216. test_streq(k, "k8");
  217. test_streq(v, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
  218. tor_free(k); tor_free(v);
  219. str = parse_config_line_from_str(str, &k, &v);
  220. test_streq(k, "k9");
  221. test_streq(v, "a line that spans two lines.");
  222. tor_free(k); tor_free(v);
  223. str = parse_config_line_from_str(str, &k, &v);
  224. test_streq(k, "k10");
  225. test_streq(v, "more than one continuation");
  226. tor_free(k); tor_free(v);
  227. str = parse_config_line_from_str(str, &k, &v);
  228. test_streq(k, "k11");
  229. test_streq(v, "continuation at the start");
  230. tor_free(k); tor_free(v);
  231. str = parse_config_line_from_str(str, &k, &v);
  232. test_streq(k, "k12");
  233. test_streq(v, "line with a embedded");
  234. tor_free(k); tor_free(v);
  235. str = parse_config_line_from_str(str, &k, &v);
  236. test_streq(k, "k13");
  237. test_streq(v, "continuation at the very start");
  238. tor_free(k); tor_free(v);
  239. str = parse_config_line_from_str(str, &k, &v);
  240. test_streq(k, "k14");
  241. test_streq(v, "a line that has a comment and" );
  242. tor_free(k); tor_free(v);
  243. str = parse_config_line_from_str(str, &k, &v);
  244. test_streq(k, "k15");
  245. test_streq(v, "this should be the next new line");
  246. tor_free(k); tor_free(v);
  247. str = parse_config_line_from_str(str, &k, &v);
  248. test_streq(k, "k16");
  249. test_streq(v, "a line that has a comment and" );
  250. tor_free(k); tor_free(v);
  251. str = parse_config_line_from_str(str, &k, &v);
  252. test_streq(k, "k17");
  253. test_streq(v, "this should be the next new line");
  254. tor_free(k); tor_free(v);
  255. test_streq(str, "");
  256. done:
  257. tor_free(k);
  258. tor_free(v);
  259. }
  260. static void
  261. test_util_config_line_quotes(void)
  262. {
  263. char buf1[1024];
  264. char buf2[128];
  265. char buf3[128];
  266. char buf4[128];
  267. char *k=NULL, *v=NULL;
  268. const char *str;
  269. /* Test parse_config_line_from_str */
  270. strlcpy(buf1, "kTrailingSpace \"quoted value\" \n"
  271. "kTrailingGarbage \"quoted value\"trailing garbage\n"
  272. , sizeof(buf1));
  273. strlcpy(buf2, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
  274. , sizeof(buf2));
  275. strlcpy(buf3, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
  276. , sizeof(buf3));
  277. strlcpy(buf4, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
  278. , sizeof(buf4));
  279. str = buf1;
  280. str = parse_config_line_from_str(str, &k, &v);
  281. test_streq(k, "kTrailingSpace");
  282. test_streq(v, "quoted value");
  283. tor_free(k); tor_free(v);
  284. str = parse_config_line_from_str(str, &k, &v);
  285. test_eq_ptr(str, NULL);
  286. tor_free(k); tor_free(v);
  287. str = buf2;
  288. str = parse_config_line_from_str(str, &k, &v);
  289. test_eq_ptr(str, NULL);
  290. tor_free(k); tor_free(v);
  291. str = buf3;
  292. str = parse_config_line_from_str(str, &k, &v);
  293. test_eq_ptr(str, NULL);
  294. tor_free(k); tor_free(v);
  295. str = buf4;
  296. str = parse_config_line_from_str(str, &k, &v);
  297. test_eq_ptr(str, NULL);
  298. tor_free(k); tor_free(v);
  299. done:
  300. tor_free(k);
  301. tor_free(v);
  302. }
  303. static void
  304. test_util_config_line_comment_character(void)
  305. {
  306. char buf[1024];
  307. char *k=NULL, *v=NULL;
  308. const char *str;
  309. /* Test parse_config_line_from_str */
  310. strlcpy(buf, "k1 \"# in quotes\"\n"
  311. "k2 some value # some comment\n"
  312. "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
  313. , sizeof(buf));
  314. str = buf;
  315. str = parse_config_line_from_str(str, &k, &v);
  316. test_streq(k, "k1");
  317. test_streq(v, "# in quotes");
  318. tor_free(k); tor_free(v);
  319. str = parse_config_line_from_str(str, &k, &v);
  320. test_streq(k, "k2");
  321. test_streq(v, "some value");
  322. tor_free(k); tor_free(v);
  323. test_streq(str, "k3 /home/user/myTorNetwork#2\n");
  324. #if 0
  325. str = parse_config_line_from_str(str, &k, &v);
  326. test_streq(k, "k3");
  327. test_streq(v, "/home/user/myTorNetwork#2");
  328. tor_free(k); tor_free(v);
  329. test_streq(str, "");
  330. #endif
  331. done:
  332. tor_free(k);
  333. tor_free(v);
  334. }
  335. static void
  336. test_util_config_line_escaped_content(void)
  337. {
  338. char buf1[1024];
  339. char buf2[128];
  340. char buf3[128];
  341. char buf4[128];
  342. char buf5[128];
  343. char buf6[128];
  344. char *k=NULL, *v=NULL;
  345. const char *str;
  346. /* Test parse_config_line_from_str */
  347. strlcpy(buf1, "HexadecimalLower \"\\x2a\"\n"
  348. "HexadecimalUpper \"\\x2A\"\n"
  349. "HexadecimalUpperX \"\\X2A\"\n"
  350. "Octal \"\\52\"\n"
  351. "Newline \"\\n\"\n"
  352. "Tab \"\\t\"\n"
  353. "CarriageReturn \"\\r\"\n"
  354. "DoubleQuote \"\\\"\"\n"
  355. "SimpleQuote \"\\'\"\n"
  356. "Backslash \"\\\\\"\n"
  357. "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
  358. , sizeof(buf1));
  359. strlcpy(buf2, "BrokenEscapedContent \"\\a\"\n"
  360. , sizeof(buf2));
  361. strlcpy(buf3, "BrokenEscapedContent \"\\x\"\n"
  362. , sizeof(buf3));
  363. strlcpy(buf4, "BrokenOctal \"\\8\"\n"
  364. , sizeof(buf4));
  365. strlcpy(buf5, "BrokenHex \"\\xg4\"\n"
  366. , sizeof(buf5));
  367. strlcpy(buf6, "BrokenEscape \"\\"
  368. , sizeof(buf6));
  369. str = buf1;
  370. str = parse_config_line_from_str(str, &k, &v);
  371. test_streq(k, "HexadecimalLower");
  372. test_streq(v, "*");
  373. tor_free(k); tor_free(v);
  374. str = parse_config_line_from_str(str, &k, &v);
  375. test_streq(k, "HexadecimalUpper");
  376. test_streq(v, "*");
  377. tor_free(k); tor_free(v);
  378. str = parse_config_line_from_str(str, &k, &v);
  379. test_streq(k, "HexadecimalUpperX");
  380. test_streq(v, "*");
  381. tor_free(k); tor_free(v);
  382. str = parse_config_line_from_str(str, &k, &v);
  383. test_streq(k, "Octal");
  384. test_streq(v, "*");
  385. tor_free(k); tor_free(v);
  386. str = parse_config_line_from_str(str, &k, &v);
  387. test_streq(k, "Newline");
  388. test_streq(v, "\n");
  389. tor_free(k); tor_free(v);
  390. str = parse_config_line_from_str(str, &k, &v);
  391. test_streq(k, "Tab");
  392. test_streq(v, "\t");
  393. tor_free(k); tor_free(v);
  394. str = parse_config_line_from_str(str, &k, &v);
  395. test_streq(k, "CarriageReturn");
  396. test_streq(v, "\r");
  397. tor_free(k); tor_free(v);
  398. str = parse_config_line_from_str(str, &k, &v);
  399. test_streq(k, "DoubleQuote");
  400. test_streq(v, "\"");
  401. tor_free(k); tor_free(v);
  402. str = parse_config_line_from_str(str, &k, &v);
  403. test_streq(k, "SimpleQuote");
  404. test_streq(v, "'");
  405. tor_free(k); tor_free(v);
  406. str = parse_config_line_from_str(str, &k, &v);
  407. test_streq(k, "Backslash");
  408. test_streq(v, "\\");
  409. tor_free(k); tor_free(v);
  410. str = parse_config_line_from_str(str, &k, &v);
  411. test_streq(k, "Mix");
  412. test_streq(v, "This is a \"star\":\t'*'\nAnd second line");
  413. tor_free(k); tor_free(v);
  414. test_streq(str, "");
  415. str = buf2;
  416. str = parse_config_line_from_str(str, &k, &v);
  417. test_eq_ptr(str, NULL);
  418. tor_free(k); tor_free(v);
  419. str = buf3;
  420. str = parse_config_line_from_str(str, &k, &v);
  421. test_eq_ptr(str, NULL);
  422. tor_free(k); tor_free(v);
  423. str = buf4;
  424. str = parse_config_line_from_str(str, &k, &v);
  425. test_eq_ptr(str, NULL);
  426. tor_free(k); tor_free(v);
  427. #if 0
  428. str = buf5;
  429. str = parse_config_line_from_str(str, &k, &v);
  430. test_eq_ptr(str, NULL);
  431. tor_free(k); tor_free(v);
  432. #endif
  433. str = buf6;
  434. str = parse_config_line_from_str(str, &k, &v);
  435. test_eq_ptr(str, NULL);
  436. tor_free(k); tor_free(v);
  437. done:
  438. tor_free(k);
  439. tor_free(v);
  440. }
  441. #ifndef _WIN32
  442. static void
  443. test_util_expand_filename(void)
  444. {
  445. char *str;
  446. setenv("HOME", "/home/itv", 1); /* For "internal test value" */
  447. str = expand_filename("");
  448. test_streq("", str);
  449. tor_free(str);
  450. str = expand_filename("/normal/path");
  451. test_streq("/normal/path", str);
  452. tor_free(str);
  453. str = expand_filename("/normal/trailing/path/");
  454. test_streq("/normal/trailing/path/", str);
  455. tor_free(str);
  456. str = expand_filename("~");
  457. test_streq("/home/itv/", str);
  458. tor_free(str);
  459. str = expand_filename("$HOME/nodice");
  460. test_streq("$HOME/nodice", str);
  461. tor_free(str);
  462. str = expand_filename("~/");
  463. test_streq("/home/itv/", str);
  464. tor_free(str);
  465. str = expand_filename("~/foobarqux");
  466. test_streq("/home/itv/foobarqux", str);
  467. tor_free(str);
  468. str = expand_filename("~/../../etc/passwd");
  469. test_streq("/home/itv/../../etc/passwd", str);
  470. tor_free(str);
  471. str = expand_filename("~/trailing/");
  472. test_streq("/home/itv/trailing/", str);
  473. tor_free(str);
  474. /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
  475. have to somehow inject/fake the get_user_homedir call) */
  476. /* $HOME ending in a trailing slash */
  477. setenv("HOME", "/home/itv/", 1);
  478. str = expand_filename("~");
  479. test_streq("/home/itv/", str);
  480. tor_free(str);
  481. str = expand_filename("~/");
  482. test_streq("/home/itv/", str);
  483. tor_free(str);
  484. str = expand_filename("~/foo");
  485. test_streq("/home/itv/foo", str);
  486. tor_free(str);
  487. /* Try with empty $HOME */
  488. setenv("HOME", "", 1);
  489. str = expand_filename("~");
  490. test_streq("/", str);
  491. tor_free(str);
  492. str = expand_filename("~/");
  493. test_streq("/", str);
  494. tor_free(str);
  495. str = expand_filename("~/foobar");
  496. test_streq("/foobar", str);
  497. tor_free(str);
  498. /* Try with $HOME unset */
  499. unsetenv("HOME");
  500. str = expand_filename("~");
  501. test_streq("/", str);
  502. tor_free(str);
  503. str = expand_filename("~/");
  504. test_streq("/", str);
  505. tor_free(str);
  506. str = expand_filename("~/foobar");
  507. test_streq("/foobar", str);
  508. tor_free(str);
  509. done:
  510. tor_free(str);
  511. }
  512. #endif
  513. /** Test basic string functionality. */
  514. static void
  515. test_util_strmisc(void)
  516. {
  517. char buf[1024];
  518. int i;
  519. char *cp;
  520. /* Test strl operations */
  521. test_eq(5, strlcpy(buf, "Hello", 0));
  522. test_eq(5, strlcpy(buf, "Hello", 10));
  523. test_streq(buf, "Hello");
  524. test_eq(5, strlcpy(buf, "Hello", 6));
  525. test_streq(buf, "Hello");
  526. test_eq(5, strlcpy(buf, "Hello", 5));
  527. test_streq(buf, "Hell");
  528. strlcpy(buf, "Hello", sizeof(buf));
  529. test_eq(10, strlcat(buf, "Hello", 5));
  530. /* Test strstrip() */
  531. strlcpy(buf, "Testing 1 2 3", sizeof(buf));
  532. tor_strstrip(buf, ",!");
  533. test_streq(buf, "Testing 1 2 3");
  534. strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
  535. tor_strstrip(buf, "!? ");
  536. test_streq(buf, "Testing123");
  537. strlcpy(buf, "!!!Testing 1 2 3??", sizeof(buf));
  538. tor_strstrip(buf, "!? ");
  539. test_streq(buf, "Testing123");
  540. /* Test parse_long */
  541. /* Empty/zero input */
  542. test_eq(0L, tor_parse_long("",10,0,100,&i,NULL));
  543. test_eq(0, i);
  544. test_eq(0L, tor_parse_long("0",10,0,100,&i,NULL));
  545. test_eq(1, i);
  546. /* Normal cases */
  547. test_eq(10L, tor_parse_long("10",10,0,100,&i,NULL));
  548. test_eq(1, i);
  549. test_eq(10L, tor_parse_long("10",10,0,10,&i,NULL));
  550. test_eq(1, i);
  551. test_eq(10L, tor_parse_long("10",10,10,100,&i,NULL));
  552. test_eq(1, i);
  553. test_eq(-50L, tor_parse_long("-50",10,-100,100,&i,NULL));
  554. test_eq(1, i);
  555. test_eq(-50L, tor_parse_long("-50",10,-100,0,&i,NULL));
  556. test_eq(1, i);
  557. test_eq(-50L, tor_parse_long("-50",10,-50,0,&i,NULL));
  558. test_eq(1, i);
  559. /* Extra garbage */
  560. test_eq(0L, tor_parse_long("10m",10,0,100,&i,NULL));
  561. test_eq(0, i);
  562. test_eq(0L, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
  563. test_eq(0, i);
  564. test_eq(10L, tor_parse_long("10m",10,0,100,&i,&cp));
  565. test_eq(1, i);
  566. test_streq(cp, "m");
  567. test_eq(-50L, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
  568. test_eq(1, i);
  569. test_streq(cp, " plus garbage");
  570. /* Out of bounds */
  571. test_eq(0L, tor_parse_long("10",10,50,100,&i,NULL));
  572. test_eq(0, i);
  573. test_eq(0L, tor_parse_long("-50",10,0,100,&i,NULL));
  574. test_eq(0, i);
  575. /* Base different than 10 */
  576. test_eq(2L, tor_parse_long("10",2,0,100,NULL,NULL));
  577. test_eq(0L, tor_parse_long("2",2,0,100,NULL,NULL));
  578. test_eq(0L, tor_parse_long("10",-2,0,100,NULL,NULL));
  579. test_eq(68284L, tor_parse_long("10abc",16,0,70000,NULL,NULL));
  580. test_eq(68284L, tor_parse_long("10ABC",16,0,70000,NULL,NULL));
  581. /* Test parse_ulong */
  582. test_eq(0UL, tor_parse_ulong("",10,0,100,NULL,NULL));
  583. test_eq(0UL, tor_parse_ulong("0",10,0,100,NULL,NULL));
  584. test_eq(10UL, tor_parse_ulong("10",10,0,100,NULL,NULL));
  585. test_eq(0UL, tor_parse_ulong("10",10,50,100,NULL,NULL));
  586. test_eq(10UL, tor_parse_ulong("10",10,0,10,NULL,NULL));
  587. test_eq(10UL, tor_parse_ulong("10",10,10,100,NULL,NULL));
  588. test_eq(0UL, tor_parse_ulong("8",8,0,100,NULL,NULL));
  589. test_eq(50UL, tor_parse_ulong("50",10,50,100,NULL,NULL));
  590. test_eq(0UL, tor_parse_ulong("-50",10,-100,100,NULL,NULL));
  591. /* Test parse_uint64 */
  592. test_assert(U64_LITERAL(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
  593. test_eq(1, i);
  594. test_streq(cp, " x");
  595. test_assert(U64_LITERAL(12345678901) ==
  596. tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
  597. test_eq(1, i);
  598. test_streq(cp, "");
  599. test_assert(U64_LITERAL(0) ==
  600. tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
  601. test_eq(0, i);
  602. {
  603. /* Test parse_double */
  604. double d = tor_parse_double("10", 0, UINT64_MAX,&i,NULL);
  605. test_eq(1, i);
  606. test_assert(DBL_TO_U64(d) == 10);
  607. d = tor_parse_double("0", 0, UINT64_MAX,&i,NULL);
  608. test_eq(1, i);
  609. test_assert(DBL_TO_U64(d) == 0);
  610. d = tor_parse_double(" ", 0, UINT64_MAX,&i,NULL);
  611. test_eq(0, i);
  612. d = tor_parse_double(".0a", 0, UINT64_MAX,&i,NULL);
  613. test_eq(0, i);
  614. d = tor_parse_double(".0a", 0, UINT64_MAX,&i,&cp);
  615. test_eq(1, i);
  616. d = tor_parse_double("-.0", 0, UINT64_MAX,&i,NULL);
  617. test_eq(1, i);
  618. test_assert(DBL_TO_U64(d) == 0);
  619. d = tor_parse_double("-10", -100.0, 100.0,&i,NULL);
  620. test_eq(1, i);
  621. test_eq(-10.0, d);
  622. }
  623. {
  624. /* Test tor_parse_* where we overflow/underflow the underlying type. */
  625. /* This string should overflow 64-bit ints. */
  626. #define TOOBIG "100000000000000000000000000"
  627. test_eq(0L, tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
  628. test_eq(i, 0);
  629. test_eq(0L, tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
  630. test_eq(i, 0);
  631. test_eq(0UL, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
  632. test_eq(i, 0);
  633. test_eq(U64_LITERAL(0), tor_parse_uint64(TOOBIG, 10,
  634. 0, UINT64_MAX, &i, NULL));
  635. test_eq(i, 0);
  636. }
  637. /* Test snprintf */
  638. /* Returning -1 when there's not enough room in the output buffer */
  639. test_eq(-1, tor_snprintf(buf, 0, "Foo"));
  640. test_eq(-1, tor_snprintf(buf, 2, "Foo"));
  641. test_eq(-1, tor_snprintf(buf, 3, "Foo"));
  642. test_neq(-1, tor_snprintf(buf, 4, "Foo"));
  643. /* Always NUL-terminate the output */
  644. tor_snprintf(buf, 5, "abcdef");
  645. test_eq(0, buf[4]);
  646. tor_snprintf(buf, 10, "abcdef");
  647. test_eq(0, buf[6]);
  648. /* uint64 */
  649. tor_snprintf(buf, sizeof(buf), "x!"U64_FORMAT"!x",
  650. U64_PRINTF_ARG(U64_LITERAL(12345678901)));
  651. test_streq("x!12345678901!x", buf);
  652. /* Test str{,case}cmpstart */
  653. test_assert(strcmpstart("abcdef", "abcdef")==0);
  654. test_assert(strcmpstart("abcdef", "abc")==0);
  655. test_assert(strcmpstart("abcdef", "abd")<0);
  656. test_assert(strcmpstart("abcdef", "abb")>0);
  657. test_assert(strcmpstart("ab", "abb")<0);
  658. test_assert(strcmpstart("ab", "")==0);
  659. test_assert(strcmpstart("ab", "ab ")<0);
  660. test_assert(strcasecmpstart("abcdef", "abCdEF")==0);
  661. test_assert(strcasecmpstart("abcDeF", "abc")==0);
  662. test_assert(strcasecmpstart("abcdef", "Abd")<0);
  663. test_assert(strcasecmpstart("Abcdef", "abb")>0);
  664. test_assert(strcasecmpstart("ab", "Abb")<0);
  665. test_assert(strcasecmpstart("ab", "")==0);
  666. test_assert(strcasecmpstart("ab", "ab ")<0);
  667. /* Test str{,case}cmpend */
  668. test_assert(strcmpend("abcdef", "abcdef")==0);
  669. test_assert(strcmpend("abcdef", "def")==0);
  670. test_assert(strcmpend("abcdef", "deg")<0);
  671. test_assert(strcmpend("abcdef", "dee")>0);
  672. test_assert(strcmpend("ab", "aab")>0);
  673. test_assert(strcasecmpend("AbcDEF", "abcdef")==0);
  674. test_assert(strcasecmpend("abcdef", "dEF")==0);
  675. test_assert(strcasecmpend("abcdef", "Deg")<0);
  676. test_assert(strcasecmpend("abcDef", "dee")>0);
  677. test_assert(strcasecmpend("AB", "abb")<0);
  678. /* Test digest_is_zero */
  679. memset(buf,0,20);
  680. buf[20] = 'x';
  681. test_assert(tor_digest_is_zero(buf));
  682. buf[19] = 'x';
  683. test_assert(!tor_digest_is_zero(buf));
  684. /* Test mem_is_zero */
  685. memset(buf,0,128);
  686. buf[128] = 'x';
  687. test_assert(tor_mem_is_zero(buf, 10));
  688. test_assert(tor_mem_is_zero(buf, 20));
  689. test_assert(tor_mem_is_zero(buf, 128));
  690. test_assert(!tor_mem_is_zero(buf, 129));
  691. buf[60] = (char)255;
  692. test_assert(!tor_mem_is_zero(buf, 128));
  693. buf[0] = (char)1;
  694. test_assert(!tor_mem_is_zero(buf, 10));
  695. /* Test 'escaped' */
  696. test_assert(NULL == escaped(NULL));
  697. test_streq("\"\"", escaped(""));
  698. test_streq("\"abcd\"", escaped("abcd"));
  699. test_streq("\"\\\\ \\n\\r\\t\\\"\\'\"", escaped("\\ \n\r\t\"'"));
  700. test_streq("\"unnecessary \\'backslashes\\'\"",
  701. escaped("unnecessary \'backslashes\'"));
  702. /* Non-printable characters appear as octal */
  703. test_streq("\"z\\001abc\\277d\"", escaped("z\001abc\277d"));
  704. test_streq("\"z\\336\\255 ;foo\"", escaped("z\xde\xad\x20;foo"));
  705. /* Test strndup and memdup */
  706. {
  707. const char *s = "abcdefghijklmnopqrstuvwxyz";
  708. cp = tor_strndup(s, 30);
  709. test_streq(cp, s); /* same string, */
  710. test_neq(cp, s); /* but different pointers. */
  711. tor_free(cp);
  712. cp = tor_strndup(s, 5);
  713. test_streq(cp, "abcde");
  714. tor_free(cp);
  715. s = "a\0b\0c\0d\0e\0";
  716. cp = tor_memdup(s,10);
  717. test_memeq(cp, s, 10); /* same ram, */
  718. test_neq(cp, s); /* but different pointers. */
  719. tor_free(cp);
  720. }
  721. /* Test str-foo functions */
  722. cp = tor_strdup("abcdef");
  723. test_assert(tor_strisnonupper(cp));
  724. cp[3] = 'D';
  725. test_assert(!tor_strisnonupper(cp));
  726. tor_strupper(cp);
  727. test_streq(cp, "ABCDEF");
  728. tor_strlower(cp);
  729. test_streq(cp, "abcdef");
  730. test_assert(tor_strisnonupper(cp));
  731. test_assert(tor_strisprint(cp));
  732. cp[3] = 3;
  733. test_assert(!tor_strisprint(cp));
  734. tor_free(cp);
  735. /* Test memmem and memstr */
  736. {
  737. const char *haystack = "abcde";
  738. test_assert(!tor_memmem(haystack, 5, "ef", 2));
  739. test_eq_ptr(tor_memmem(haystack, 5, "cd", 2), haystack + 2);
  740. test_eq_ptr(tor_memmem(haystack, 5, "cde", 3), haystack + 2);
  741. test_assert(!tor_memmem(haystack, 4, "cde", 3));
  742. haystack = "ababcad";
  743. test_eq_ptr(tor_memmem(haystack, 7, "abc", 3), haystack + 2);
  744. /* memstr */
  745. test_eq_ptr(tor_memstr(haystack, 7, "abc"), haystack + 2);
  746. test_eq_ptr(tor_memstr(haystack, 7, "cad"), haystack + 4);
  747. test_assert(!tor_memstr(haystack, 6, "cad"));
  748. test_assert(!tor_memstr(haystack, 7, "cadd"));
  749. test_assert(!tor_memstr(haystack, 7, "fe"));
  750. test_assert(!tor_memstr(haystack, 7, "ababcade"));
  751. }
  752. /* Test wrap_string */
  753. {
  754. smartlist_t *sl = smartlist_new();
  755. wrap_string(sl,
  756. "This is a test of string wrapping functionality: woot. "
  757. "a functionality? w00t w00t...!",
  758. 10, "", "");
  759. cp = smartlist_join_strings(sl, "", 0, NULL);
  760. test_streq(cp,
  761. "This is a\ntest of\nstring\nwrapping\nfunctional\nity: woot.\n"
  762. "a\nfunctional\nity? w00t\nw00t...!\n");
  763. tor_free(cp);
  764. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  765. smartlist_clear(sl);
  766. wrap_string(sl, "This is a test of string wrapping functionality: woot.",
  767. 16, "### ", "# ");
  768. cp = smartlist_join_strings(sl, "", 0, NULL);
  769. test_streq(cp,
  770. "### This is a\n# test of string\n# wrapping\n# functionality:\n"
  771. "# woot.\n");
  772. tor_free(cp);
  773. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  774. smartlist_clear(sl);
  775. wrap_string(sl, "A test of string wrapping...", 6, "### ", "# ");
  776. cp = smartlist_join_strings(sl, "", 0, NULL);
  777. test_streq(cp,
  778. "### A\n# test\n# of\n# stri\n# ng\n# wrap\n# ping\n# ...\n");
  779. tor_free(cp);
  780. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  781. smartlist_clear(sl);
  782. wrap_string(sl, "Wrapping test", 6, "#### ", "# ");
  783. cp = smartlist_join_strings(sl, "", 0, NULL);
  784. test_streq(cp, "#### W\n# rapp\n# ing\n# test\n");
  785. tor_free(cp);
  786. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  787. smartlist_clear(sl);
  788. wrap_string(sl, "Small test", 6, "### ", "#### ");
  789. cp = smartlist_join_strings(sl, "", 0, NULL);
  790. test_streq(cp, "### Sm\n#### a\n#### l\n#### l\n#### t\n#### e"
  791. "\n#### s\n#### t\n");
  792. tor_free(cp);
  793. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  794. smartlist_clear(sl);
  795. wrap_string(sl, "First null", 6, NULL, "> ");
  796. cp = smartlist_join_strings(sl, "", 0, NULL);
  797. test_streq(cp, "First\n> null\n");
  798. tor_free(cp);
  799. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  800. smartlist_clear(sl);
  801. wrap_string(sl, "Second null", 6, "> ", NULL);
  802. cp = smartlist_join_strings(sl, "", 0, NULL);
  803. test_streq(cp, "> Seco\nnd\nnull\n");
  804. tor_free(cp);
  805. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  806. smartlist_clear(sl);
  807. wrap_string(sl, "Both null", 6, NULL, NULL);
  808. cp = smartlist_join_strings(sl, "", 0, NULL);
  809. test_streq(cp, "Both\nnull\n");
  810. tor_free(cp);
  811. SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
  812. smartlist_free(sl);
  813. /* Can't test prefixes that have the same length as the line width, because
  814. the function has an assert */
  815. }
  816. /* Test hex_str */
  817. {
  818. char binary_data[68];
  819. size_t i;
  820. for (i = 0; i < sizeof(binary_data); ++i)
  821. binary_data[i] = i;
  822. test_streq(hex_str(binary_data, 0), "");
  823. test_streq(hex_str(binary_data, 1), "00");
  824. test_streq(hex_str(binary_data, 17), "000102030405060708090A0B0C0D0E0F10");
  825. test_streq(hex_str(binary_data, 32),
  826. "000102030405060708090A0B0C0D0E0F"
  827. "101112131415161718191A1B1C1D1E1F");
  828. test_streq(hex_str(binary_data, 34),
  829. "000102030405060708090A0B0C0D0E0F"
  830. "101112131415161718191A1B1C1D1E1F");
  831. /* Repeat these tests for shorter strings after longer strings
  832. have been tried, to make sure we're correctly terminating strings */
  833. test_streq(hex_str(binary_data, 1), "00");
  834. test_streq(hex_str(binary_data, 0), "");
  835. }
  836. /* Test strcmp_opt */
  837. tt_int_op(strcmp_opt("", "foo"), <, 0);
  838. tt_int_op(strcmp_opt("", ""), ==, 0);
  839. tt_int_op(strcmp_opt("foo", ""), >, 0);
  840. tt_int_op(strcmp_opt(NULL, ""), <, 0);
  841. tt_int_op(strcmp_opt(NULL, NULL), ==, 0);
  842. tt_int_op(strcmp_opt("", NULL), >, 0);
  843. tt_int_op(strcmp_opt(NULL, "foo"), <, 0);
  844. tt_int_op(strcmp_opt("foo", NULL), >, 0);
  845. /* Test strcmp_len */
  846. tt_int_op(strcmp_len("foo", "bar", 3), >, 0);
  847. tt_int_op(strcmp_len("foo", "bar", 2), <, 0); /* First len, then lexical */
  848. tt_int_op(strcmp_len("foo2", "foo1", 4), >, 0);
  849. tt_int_op(strcmp_len("foo2", "foo1", 3), <, 0); /* Really stop at len */
  850. tt_int_op(strcmp_len("foo2", "foo", 3), ==, 0); /* Really stop at len */
  851. tt_int_op(strcmp_len("blah", "", 4), >, 0);
  852. tt_int_op(strcmp_len("blah", "", 0), ==, 0);
  853. done:
  854. ;
  855. }
  856. static void
  857. test_util_pow2(void)
  858. {
  859. /* Test tor_log2(). */
  860. test_eq(tor_log2(64), 6);
  861. test_eq(tor_log2(65), 6);
  862. test_eq(tor_log2(63), 5);
  863. test_eq(tor_log2(1), 0);
  864. test_eq(tor_log2(2), 1);
  865. test_eq(tor_log2(3), 1);
  866. test_eq(tor_log2(4), 2);
  867. test_eq(tor_log2(5), 2);
  868. test_eq(tor_log2(U64_LITERAL(40000000000000000)), 55);
  869. test_eq(tor_log2(UINT64_MAX), 63);
  870. /* Test round_to_power_of_2 */
  871. test_eq(round_to_power_of_2(120), 128);
  872. test_eq(round_to_power_of_2(128), 128);
  873. test_eq(round_to_power_of_2(130), 128);
  874. test_eq(round_to_power_of_2(U64_LITERAL(40000000000000000)),
  875. U64_LITERAL(1)<<55);
  876. test_eq(round_to_power_of_2(0), 2);
  877. done:
  878. ;
  879. }
  880. /** mutex for thread test to stop the threads hitting data at the same time. */
  881. static tor_mutex_t *_thread_test_mutex = NULL;
  882. /** mutexes for the thread test to make sure that the threads have to
  883. * interleave somewhat. */
  884. static tor_mutex_t *_thread_test_start1 = NULL,
  885. *_thread_test_start2 = NULL;
  886. /** Shared strmap for the thread test. */
  887. static strmap_t *_thread_test_strmap = NULL;
  888. /** The name of thread1 for the thread test */
  889. static char *_thread1_name = NULL;
  890. /** The name of thread2 for the thread test */
  891. static char *_thread2_name = NULL;
  892. static void _thread_test_func(void* _s) ATTR_NORETURN;
  893. /** How many iterations have the threads in the unit test run? */
  894. static int t1_count = 0, t2_count = 0;
  895. /** Helper function for threading unit tests: This function runs in a
  896. * subthread. It grabs its own mutex (start1 or start2) to make sure that it
  897. * should start, then it repeatedly alters _test_thread_strmap protected by
  898. * _thread_test_mutex. */
  899. static void
  900. _thread_test_func(void* _s)
  901. {
  902. char *s = _s;
  903. int i, *count;
  904. tor_mutex_t *m;
  905. char buf[64];
  906. char **cp;
  907. if (!strcmp(s, "thread 1")) {
  908. m = _thread_test_start1;
  909. cp = &_thread1_name;
  910. count = &t1_count;
  911. } else {
  912. m = _thread_test_start2;
  913. cp = &_thread2_name;
  914. count = &t2_count;
  915. }
  916. tor_snprintf(buf, sizeof(buf), "%lu", tor_get_thread_id());
  917. *cp = tor_strdup(buf);
  918. tor_mutex_acquire(m);
  919. for (i=0; i<10000; ++i) {
  920. tor_mutex_acquire(_thread_test_mutex);
  921. strmap_set(_thread_test_strmap, "last to run", *cp);
  922. ++*count;
  923. tor_mutex_release(_thread_test_mutex);
  924. }
  925. tor_mutex_acquire(_thread_test_mutex);
  926. strmap_set(_thread_test_strmap, s, *cp);
  927. tor_mutex_release(_thread_test_mutex);
  928. tor_mutex_release(m);
  929. spawn_exit();
  930. }
  931. /** Run unit tests for threading logic. */
  932. static void
  933. test_util_threads(void)
  934. {
  935. char *s1 = NULL, *s2 = NULL;
  936. int done = 0, timedout = 0;
  937. time_t started;
  938. #ifndef _WIN32
  939. struct timeval tv;
  940. tv.tv_sec=0;
  941. tv.tv_usec=10;
  942. #endif
  943. #ifndef TOR_IS_MULTITHREADED
  944. /* Skip this test if we aren't threading. We should be threading most
  945. * everywhere by now. */
  946. if (1)
  947. return;
  948. #endif
  949. _thread_test_mutex = tor_mutex_new();
  950. _thread_test_start1 = tor_mutex_new();
  951. _thread_test_start2 = tor_mutex_new();
  952. _thread_test_strmap = strmap_new();
  953. s1 = tor_strdup("thread 1");
  954. s2 = tor_strdup("thread 2");
  955. tor_mutex_acquire(_thread_test_start1);
  956. tor_mutex_acquire(_thread_test_start2);
  957. spawn_func(_thread_test_func, s1);
  958. spawn_func(_thread_test_func, s2);
  959. tor_mutex_release(_thread_test_start2);
  960. tor_mutex_release(_thread_test_start1);
  961. started = time(NULL);
  962. while (!done) {
  963. tor_mutex_acquire(_thread_test_mutex);
  964. strmap_assert_ok(_thread_test_strmap);
  965. if (strmap_get(_thread_test_strmap, "thread 1") &&
  966. strmap_get(_thread_test_strmap, "thread 2")) {
  967. done = 1;
  968. } else if (time(NULL) > started + 25) {
  969. timedout = done = 1;
  970. }
  971. tor_mutex_release(_thread_test_mutex);
  972. #ifndef _WIN32
  973. /* Prevent the main thread from starving the worker threads. */
  974. select(0, NULL, NULL, NULL, &tv);
  975. #endif
  976. }
  977. tor_mutex_acquire(_thread_test_start1);
  978. tor_mutex_release(_thread_test_start1);
  979. tor_mutex_acquire(_thread_test_start2);
  980. tor_mutex_release(_thread_test_start2);
  981. tor_mutex_free(_thread_test_mutex);
  982. if (timedout) {
  983. printf("\nTimed out: %d %d", t1_count, t2_count);
  984. test_assert(strmap_get(_thread_test_strmap, "thread 1"));
  985. test_assert(strmap_get(_thread_test_strmap, "thread 2"));
  986. test_assert(!timedout);
  987. }
  988. /* different thread IDs. */
  989. test_assert(strcmp(strmap_get(_thread_test_strmap, "thread 1"),
  990. strmap_get(_thread_test_strmap, "thread 2")));
  991. test_assert(!strcmp(strmap_get(_thread_test_strmap, "thread 1"),
  992. strmap_get(_thread_test_strmap, "last to run")) ||
  993. !strcmp(strmap_get(_thread_test_strmap, "thread 2"),
  994. strmap_get(_thread_test_strmap, "last to run")));
  995. done:
  996. tor_free(s1);
  997. tor_free(s2);
  998. tor_free(_thread1_name);
  999. tor_free(_thread2_name);
  1000. if (_thread_test_strmap)
  1001. strmap_free(_thread_test_strmap, NULL);
  1002. if (_thread_test_start1)
  1003. tor_mutex_free(_thread_test_start1);
  1004. if (_thread_test_start2)
  1005. tor_mutex_free(_thread_test_start2);
  1006. }
  1007. /** Run unit tests for compression functions */
  1008. static void
  1009. test_util_gzip(void)
  1010. {
  1011. char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2;
  1012. const char *ccp2;
  1013. size_t len1, len2;
  1014. tor_zlib_state_t *state = NULL;
  1015. buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
  1016. test_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
  1017. if (is_gzip_supported()) {
  1018. test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  1019. GZIP_METHOD));
  1020. test_assert(buf2);
  1021. test_assert(len1 < strlen(buf1));
  1022. test_assert(detect_compression_method(buf2, len1) == GZIP_METHOD);
  1023. test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
  1024. GZIP_METHOD, 1, LOG_INFO));
  1025. test_assert(buf3);
  1026. test_eq(strlen(buf1) + 1, len2);
  1027. test_streq(buf1, buf3);
  1028. tor_free(buf2);
  1029. tor_free(buf3);
  1030. }
  1031. test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  1032. ZLIB_METHOD));
  1033. test_assert(buf2);
  1034. test_assert(detect_compression_method(buf2, len1) == ZLIB_METHOD);
  1035. test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1,
  1036. ZLIB_METHOD, 1, LOG_INFO));
  1037. test_assert(buf3);
  1038. test_eq(strlen(buf1) + 1, len2);
  1039. test_streq(buf1, buf3);
  1040. /* Check whether we can uncompress concatenated, compressed strings. */
  1041. tor_free(buf3);
  1042. buf2 = tor_realloc(buf2, len1*2);
  1043. memcpy(buf2+len1, buf2, len1);
  1044. test_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1*2,
  1045. ZLIB_METHOD, 1, LOG_INFO));
  1046. test_eq((strlen(buf1)+1)*2, len2);
  1047. test_memeq(buf3,
  1048. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
  1049. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
  1050. (strlen(buf1)+1)*2);
  1051. tor_free(buf1);
  1052. tor_free(buf2);
  1053. tor_free(buf3);
  1054. /* Check whether we can uncompress partial strings. */
  1055. buf1 =
  1056. tor_strdup("String with low redundancy that won't be compressed much.");
  1057. test_assert(!tor_gzip_compress(&buf2, &len1, buf1, strlen(buf1)+1,
  1058. ZLIB_METHOD));
  1059. tt_assert(len1>16);
  1060. /* when we allow an incomplete string, we should succeed.*/
  1061. tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
  1062. ZLIB_METHOD, 0, LOG_INFO));
  1063. tt_assert(len2 > 5);
  1064. buf3[len2]='\0';
  1065. tt_assert(!strcmpstart(buf1, buf3));
  1066. /* when we demand a complete string, this must fail. */
  1067. tor_free(buf3);
  1068. tt_assert(tor_gzip_uncompress(&buf3, &len2, buf2, len1-16,
  1069. ZLIB_METHOD, 1, LOG_INFO));
  1070. tt_assert(!buf3);
  1071. /* Now, try streaming compression. */
  1072. tor_free(buf1);
  1073. tor_free(buf2);
  1074. tor_free(buf3);
  1075. state = tor_zlib_new(1, ZLIB_METHOD);
  1076. tt_assert(state);
  1077. cp1 = buf1 = tor_malloc(1024);
  1078. len1 = 1024;
  1079. ccp2 = "ABCDEFGHIJABCDEFGHIJ";
  1080. len2 = 21;
  1081. test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 0)
  1082. == TOR_ZLIB_OK);
  1083. test_eq(0, len2); /* Make sure we compressed it all. */
  1084. test_assert(cp1 > buf1);
  1085. len2 = 0;
  1086. cp2 = cp1;
  1087. test_assert(tor_zlib_process(state, &cp1, &len1, &ccp2, &len2, 1)
  1088. == TOR_ZLIB_DONE);
  1089. test_eq(0, len2);
  1090. test_assert(cp1 > cp2); /* Make sure we really added something. */
  1091. tt_assert(!tor_gzip_uncompress(&buf3, &len2, buf1, 1024-len1,
  1092. ZLIB_METHOD, 1, LOG_WARN));
  1093. test_streq(buf3, "ABCDEFGHIJABCDEFGHIJ"); /*Make sure it compressed right.*/
  1094. test_eq(21, len2);
  1095. done:
  1096. if (state)
  1097. tor_zlib_free(state);
  1098. tor_free(buf2);
  1099. tor_free(buf3);
  1100. tor_free(buf1);
  1101. }
  1102. /** Run unit tests for mmap() wrapper functionality. */
  1103. static void
  1104. test_util_mmap(void)
  1105. {
  1106. char *fname1 = tor_strdup(get_fname("mapped_1"));
  1107. char *fname2 = tor_strdup(get_fname("mapped_2"));
  1108. char *fname3 = tor_strdup(get_fname("mapped_3"));
  1109. const size_t buflen = 17000;
  1110. char *buf = tor_malloc(17000);
  1111. tor_mmap_t *mapping = NULL;
  1112. crypto_rand(buf, buflen);
  1113. mapping = tor_mmap_file(fname1);
  1114. test_assert(! mapping);
  1115. write_str_to_file(fname1, "Short file.", 1);
  1116. mapping = tor_mmap_file(fname1);
  1117. test_assert(mapping);
  1118. test_eq(mapping->size, strlen("Short file."));
  1119. test_streq(mapping->data, "Short file.");
  1120. #ifdef _WIN32
  1121. tor_munmap_file(mapping);
  1122. mapping = NULL;
  1123. test_assert(unlink(fname1) == 0);
  1124. #else
  1125. /* make sure we can unlink. */
  1126. test_assert(unlink(fname1) == 0);
  1127. test_streq(mapping->data, "Short file.");
  1128. tor_munmap_file(mapping);
  1129. mapping = NULL;
  1130. #endif
  1131. /* Now a zero-length file. */
  1132. write_str_to_file(fname1, "", 1);
  1133. mapping = tor_mmap_file(fname1);
  1134. test_eq(mapping, NULL);
  1135. test_eq(ERANGE, errno);
  1136. unlink(fname1);
  1137. /* Make sure that we fail to map a no-longer-existent file. */
  1138. mapping = tor_mmap_file(fname1);
  1139. test_assert(! mapping);
  1140. /* Now try a big file that stretches across a few pages and isn't aligned */
  1141. write_bytes_to_file(fname2, buf, buflen, 1);
  1142. mapping = tor_mmap_file(fname2);
  1143. test_assert(mapping);
  1144. test_eq(mapping->size, buflen);
  1145. test_memeq(mapping->data, buf, buflen);
  1146. tor_munmap_file(mapping);
  1147. mapping = NULL;
  1148. /* Now try a big aligned file. */
  1149. write_bytes_to_file(fname3, buf, 16384, 1);
  1150. mapping = tor_mmap_file(fname3);
  1151. test_assert(mapping);
  1152. test_eq(mapping->size, 16384);
  1153. test_memeq(mapping->data, buf, 16384);
  1154. tor_munmap_file(mapping);
  1155. mapping = NULL;
  1156. done:
  1157. unlink(fname1);
  1158. unlink(fname2);
  1159. unlink(fname3);
  1160. tor_free(fname1);
  1161. tor_free(fname2);
  1162. tor_free(fname3);
  1163. tor_free(buf);
  1164. if (mapping)
  1165. tor_munmap_file(mapping);
  1166. }
  1167. /** Run unit tests for escaping/unescaping data for use by controllers. */
  1168. static void
  1169. test_util_control_formats(void)
  1170. {
  1171. char *out = NULL;
  1172. const char *inp =
  1173. "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
  1174. size_t sz;
  1175. sz = read_escaped_data(inp, strlen(inp), &out);
  1176. test_streq(out,
  1177. ".This is a test\nof the emergency \n.system.\n\rZ.\n");
  1178. test_eq(sz, strlen(out));
  1179. done:
  1180. tor_free(out);
  1181. }
  1182. static void
  1183. test_util_sscanf(void)
  1184. {
  1185. unsigned u1, u2, u3;
  1186. char s1[20], s2[10], s3[10], ch;
  1187. int r;
  1188. /* Simple tests (malformed patterns, literal matching, ...) */
  1189. test_eq(-1, tor_sscanf("123", "%i", &r)); /* %i is not supported */
  1190. test_eq(-1, tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */
  1191. test_eq(-1, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */
  1192. test_eq(-1, tor_sscanf("prettylongstring", "%999999s", s1));
  1193. #if 0
  1194. /* GCC thinks these two are illegal. */
  1195. test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1));
  1196. test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL));
  1197. #endif
  1198. /* No '%'-strings: always "success" */
  1199. test_eq(0, tor_sscanf("hello world", "hello world"));
  1200. test_eq(0, tor_sscanf("hello world", "good bye"));
  1201. /* Excess data */
  1202. test_eq(0, tor_sscanf("hello 3", "%u", &u1)); /* have to match the start */
  1203. test_eq(0, tor_sscanf(" 3 hello", "%u", &u1));
  1204. test_eq(0, tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */
  1205. test_eq(1, tor_sscanf("3 hello", "%u", &u1)); /* but trailing is alright */
  1206. /* Numbers (ie. %u) */
  1207. test_eq(0, tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */
  1208. test_eq(1, tor_sscanf("12345", "%u", &u1));
  1209. test_eq(12345u, u1);
  1210. test_eq(1, tor_sscanf("12346 ", "%u", &u1));
  1211. test_eq(12346u, u1);
  1212. test_eq(0, tor_sscanf(" 12347", "%u", &u1));
  1213. test_eq(1, tor_sscanf(" 12348", " %u", &u1));
  1214. test_eq(12348u, u1);
  1215. test_eq(1, tor_sscanf("0", "%u", &u1));
  1216. test_eq(0u, u1);
  1217. test_eq(1, tor_sscanf("0000", "%u", &u2));
  1218. test_eq(0u, u2);
  1219. test_eq(0, tor_sscanf("", "%u", &u1)); /* absent number */
  1220. test_eq(0, tor_sscanf("A", "%u", &u1)); /* bogus number */
  1221. test_eq(0, tor_sscanf("-1", "%u", &u1)); /* negative number */
  1222. test_eq(1, tor_sscanf("4294967295", "%u", &u1)); /* UINT32_MAX should work */
  1223. test_eq(4294967295u, u1);
  1224. test_eq(0, tor_sscanf("4294967296", "%u", &u1)); /* But not at 32 bits */
  1225. test_eq(1, tor_sscanf("4294967296", "%9u", &u1)); /* but parsing only 9... */
  1226. test_eq(429496729u, u1);
  1227. /* Numbers with size (eg. %2u) */
  1228. test_eq(0, tor_sscanf("-1", "%2u", &u1));
  1229. test_eq(2, tor_sscanf("123456", "%2u%u", &u1, &u2));
  1230. test_eq(12u, u1);
  1231. test_eq(3456u, u2);
  1232. test_eq(1, tor_sscanf("123456", "%8u", &u1));
  1233. test_eq(123456u, u1);
  1234. test_eq(1, tor_sscanf("123457 ", "%8u", &u1));
  1235. test_eq(123457u, u1);
  1236. test_eq(0, tor_sscanf(" 123456", "%8u", &u1));
  1237. test_eq(3, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3));
  1238. test_eq(12u, u1);
  1239. test_eq(3u, u2);
  1240. test_eq(456u, u3);
  1241. test_eq(3, tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */
  1242. test_eq(67u, u1);
  1243. test_eq(8u, u2);
  1244. test_eq(99u, u3);
  1245. /* %u does not match space.*/
  1246. test_eq(2, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3));
  1247. test_eq(12u, u1);
  1248. test_eq(3u, u2);
  1249. /* %u does not match negative numbers. */
  1250. test_eq(2, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3));
  1251. test_eq(67u, u1);
  1252. test_eq(8u, u2);
  1253. /* Arbitrary amounts of 0-padding are okay */
  1254. test_eq(3, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
  1255. &u1, &u2, &u3));
  1256. test_eq(12u, u1);
  1257. test_eq(3u, u2);
  1258. test_eq(99u, u3);
  1259. /* Hex (ie. %x) */
  1260. test_eq(3, tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3));
  1261. test_eq(0x1234, u1);
  1262. test_eq(0x2ABCDEF, u2);
  1263. test_eq(0xFF, u3);
  1264. /* Width works on %x */
  1265. test_eq(3, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3));
  1266. test_eq(0xf00d, u1);
  1267. test_eq(0xcafe, u2);
  1268. test_eq(444, u3);
  1269. /* Literal '%' (ie. '%%') */
  1270. test_eq(1, tor_sscanf("99% fresh", "%3u%% fresh", &u1));
  1271. test_eq(99, u1);
  1272. test_eq(0, tor_sscanf("99 fresh", "%% %3u %s", &u1, s1));
  1273. test_eq(1, tor_sscanf("99 fresh", "%3u%% %s", &u1, s1));
  1274. test_eq(2, tor_sscanf("99 fresh", "%3u %5s %%", &u1, s1));
  1275. test_eq(99, u1);
  1276. test_streq(s1, "fresh");
  1277. test_eq(1, tor_sscanf("% boo", "%% %3s", s1));
  1278. test_streq("boo", s1);
  1279. /* Strings (ie. %s) */
  1280. test_eq(2, tor_sscanf("hello", "%3s%7s", s1, s2));
  1281. test_streq(s1, "hel");
  1282. test_streq(s2, "lo");
  1283. test_eq(2, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */
  1284. test_streq(s3, "WD");
  1285. test_eq(40, u1);
  1286. test_eq(2, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */
  1287. test_streq(s3, "WD4");
  1288. test_eq(0, u1);
  1289. test_eq(2, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */
  1290. test_eq(76, u1);
  1291. test_streq(s1, "trombones");
  1292. test_eq(1, tor_sscanf("prettylongstring", "%999s", s1));
  1293. test_streq(s1, "prettylongstring");
  1294. /* %s doesn't eat spaces */
  1295. test_eq(2, tor_sscanf("hello world", "%9s %9s", s1, s2));
  1296. test_streq(s1, "hello");
  1297. test_streq(s2, "world");
  1298. test_eq(2, tor_sscanf("bye world?", "%9s %9s", s1, s2));
  1299. test_streq(s1, "bye");
  1300. test_streq(s2, "");
  1301. test_eq(3, tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */
  1302. test_streq(s1, "hi");
  1303. test_streq(s2, "");
  1304. test_streq(s3, "");
  1305. test_eq(3, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
  1306. test_eq(4, tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
  1307. test_eq(' ', ch);
  1308. done:
  1309. ;
  1310. }
  1311. static void
  1312. test_util_path_is_relative(void)
  1313. {
  1314. /* OS-independent tests */
  1315. test_eq(1, path_is_relative(""));
  1316. test_eq(1, path_is_relative("dir"));
  1317. test_eq(1, path_is_relative("dir/"));
  1318. test_eq(1, path_is_relative("./dir"));
  1319. test_eq(1, path_is_relative("../dir"));
  1320. test_eq(0, path_is_relative("/"));
  1321. test_eq(0, path_is_relative("/dir"));
  1322. test_eq(0, path_is_relative("/dir/"));
  1323. /* Windows */
  1324. #ifdef _WIN32
  1325. /* I don't have Windows so I can't test this, hence the "#ifdef
  1326. 0". These are tests that look useful, so please try to get them
  1327. running and uncomment if it all works as it should */
  1328. test_eq(1, path_is_relative("dir"));
  1329. test_eq(1, path_is_relative("dir\\"));
  1330. test_eq(1, path_is_relative("dir\\a:"));
  1331. test_eq(1, path_is_relative("dir\\a:\\"));
  1332. test_eq(1, path_is_relative("http:\\dir"));
  1333. test_eq(0, path_is_relative("\\dir"));
  1334. test_eq(0, path_is_relative("a:\\dir"));
  1335. test_eq(0, path_is_relative("z:\\dir"));
  1336. #endif
  1337. done:
  1338. ;
  1339. }
  1340. /** Run unittests for memory pool allocator */
  1341. static void
  1342. test_util_mempool(void)
  1343. {
  1344. mp_pool_t *pool = NULL;
  1345. smartlist_t *allocated = NULL;
  1346. int i;
  1347. pool = mp_pool_new(1, 100);
  1348. test_assert(pool);
  1349. test_assert(pool->new_chunk_capacity >= 100);
  1350. test_assert(pool->item_alloc_size >= sizeof(void*)+1);
  1351. mp_pool_destroy(pool);
  1352. pool = NULL;
  1353. pool = mp_pool_new(241, 2500);
  1354. test_assert(pool);
  1355. test_assert(pool->new_chunk_capacity >= 10);
  1356. test_assert(pool->item_alloc_size >= sizeof(void*)+241);
  1357. test_eq(pool->item_alloc_size & 0x03, 0);
  1358. test_assert(pool->new_chunk_capacity < 60);
  1359. allocated = smartlist_new();
  1360. for (i = 0; i < 20000; ++i) {
  1361. if (smartlist_len(allocated) < 20 || crypto_rand_int(2)) {
  1362. void *m = mp_pool_get(pool);
  1363. memset(m, 0x09, 241);
  1364. smartlist_add(allocated, m);
  1365. //printf("%d: %p\n", i, m);
  1366. //mp_pool_assert_ok(pool);
  1367. } else {
  1368. int idx = crypto_rand_int(smartlist_len(allocated));
  1369. void *m = smartlist_get(allocated, idx);
  1370. //printf("%d: free %p\n", i, m);
  1371. smartlist_del(allocated, idx);
  1372. mp_pool_release(m);
  1373. //mp_pool_assert_ok(pool);
  1374. }
  1375. if (crypto_rand_int(777)==0)
  1376. mp_pool_clean(pool, 1, 1);
  1377. if (i % 777)
  1378. mp_pool_assert_ok(pool);
  1379. }
  1380. done:
  1381. if (allocated) {
  1382. SMARTLIST_FOREACH(allocated, void *, m, mp_pool_release(m));
  1383. mp_pool_assert_ok(pool);
  1384. mp_pool_clean(pool, 0, 0);
  1385. mp_pool_assert_ok(pool);
  1386. smartlist_free(allocated);
  1387. }
  1388. if (pool)
  1389. mp_pool_destroy(pool);
  1390. }
  1391. /** Run unittests for memory area allocator */
  1392. static void
  1393. test_util_memarea(void)
  1394. {
  1395. memarea_t *area = memarea_new();
  1396. char *p1, *p2, *p3, *p1_orig;
  1397. void *malloced_ptr = NULL;
  1398. int i;
  1399. test_assert(area);
  1400. p1_orig = p1 = memarea_alloc(area,64);
  1401. p2 = memarea_alloc_zero(area,52);
  1402. p3 = memarea_alloc(area,11);
  1403. test_assert(memarea_owns_ptr(area, p1));
  1404. test_assert(memarea_owns_ptr(area, p2));
  1405. test_assert(memarea_owns_ptr(area, p3));
  1406. /* Make sure we left enough space. */
  1407. test_assert(p1+64 <= p2);
  1408. test_assert(p2+52 <= p3);
  1409. /* Make sure we aligned. */
  1410. test_eq(((uintptr_t)p1) % sizeof(void*), 0);
  1411. test_eq(((uintptr_t)p2) % sizeof(void*), 0);
  1412. test_eq(((uintptr_t)p3) % sizeof(void*), 0);
  1413. test_assert(!memarea_owns_ptr(area, p3+8192));
  1414. test_assert(!memarea_owns_ptr(area, p3+30));
  1415. test_assert(tor_mem_is_zero(p2, 52));
  1416. /* Make sure we don't overalign. */
  1417. p1 = memarea_alloc(area, 1);
  1418. p2 = memarea_alloc(area, 1);
  1419. test_eq(p1+sizeof(void*), p2);
  1420. {
  1421. malloced_ptr = tor_malloc(64);
  1422. test_assert(!memarea_owns_ptr(area, malloced_ptr));
  1423. tor_free(malloced_ptr);
  1424. }
  1425. /* memarea_memdup */
  1426. {
  1427. malloced_ptr = tor_malloc(64);
  1428. crypto_rand((char*)malloced_ptr, 64);
  1429. p1 = memarea_memdup(area, malloced_ptr, 64);
  1430. test_assert(p1 != malloced_ptr);
  1431. test_memeq(p1, malloced_ptr, 64);
  1432. tor_free(malloced_ptr);
  1433. }
  1434. /* memarea_strdup. */
  1435. p1 = memarea_strdup(area,"");
  1436. p2 = memarea_strdup(area, "abcd");
  1437. test_assert(p1);
  1438. test_assert(p2);
  1439. test_streq(p1, "");
  1440. test_streq(p2, "abcd");
  1441. /* memarea_strndup. */
  1442. {
  1443. const char *s = "Ad ogni porta batte la morte e grida: il nome!";
  1444. /* (From Turandot, act 3.) */
  1445. size_t len = strlen(s);
  1446. p1 = memarea_strndup(area, s, 1000);
  1447. p2 = memarea_strndup(area, s, 10);
  1448. test_streq(p1, s);
  1449. test_assert(p2 >= p1 + len + 1);
  1450. test_memeq(s, p2, 10);
  1451. test_eq(p2[10], '\0');
  1452. p3 = memarea_strndup(area, s, len);
  1453. test_streq(p3, s);
  1454. p3 = memarea_strndup(area, s, len-1);
  1455. test_memeq(s, p3, len-1);
  1456. test_eq(p3[len-1], '\0');
  1457. }
  1458. memarea_clear(area);
  1459. p1 = memarea_alloc(area, 1);
  1460. test_eq(p1, p1_orig);
  1461. memarea_clear(area);
  1462. /* Check for running over an area's size. */
  1463. for (i = 0; i < 512; ++i) {
  1464. p1 = memarea_alloc(area, crypto_rand_int(5)+1);
  1465. test_assert(memarea_owns_ptr(area, p1));
  1466. }
  1467. memarea_assert_ok(area);
  1468. /* Make sure we can allocate a too-big object. */
  1469. p1 = memarea_alloc_zero(area, 9000);
  1470. p2 = memarea_alloc_zero(area, 16);
  1471. test_assert(memarea_owns_ptr(area, p1));
  1472. test_assert(memarea_owns_ptr(area, p2));
  1473. done:
  1474. memarea_drop_all(area);
  1475. tor_free(malloced_ptr);
  1476. }
  1477. /** Run unit tests for utility functions to get file names relative to
  1478. * the data directory. */
  1479. static void
  1480. test_util_datadir(void)
  1481. {
  1482. char buf[1024];
  1483. char *f = NULL;
  1484. char *temp_dir = NULL;
  1485. temp_dir = get_datadir_fname(NULL);
  1486. f = get_datadir_fname("state");
  1487. tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir);
  1488. test_streq(f, buf);
  1489. tor_free(f);
  1490. f = get_datadir_fname2("cache", "thingy");
  1491. tor_snprintf(buf, sizeof(buf),
  1492. "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir);
  1493. test_streq(f, buf);
  1494. tor_free(f);
  1495. f = get_datadir_fname2_suffix("cache", "thingy", ".foo");
  1496. tor_snprintf(buf, sizeof(buf),
  1497. "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir);
  1498. test_streq(f, buf);
  1499. tor_free(f);
  1500. f = get_datadir_fname_suffix("cache", ".foo");
  1501. tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo",
  1502. temp_dir);
  1503. test_streq(f, buf);
  1504. done:
  1505. tor_free(f);
  1506. tor_free(temp_dir);
  1507. }
  1508. static void
  1509. test_util_strtok(void)
  1510. {
  1511. char buf[128];
  1512. char buf2[128];
  1513. int i;
  1514. char *cp1, *cp2;
  1515. for (i = 0; i < 3; i++) {
  1516. const char *pad1, *pad2;
  1517. switch (i) {
  1518. case 0:
  1519. pad1 = pad2 = "";
  1520. break;
  1521. case 1:
  1522. pad1 = " ";
  1523. pad2 = "!";
  1524. break;
  1525. case 2:
  1526. pad1 = " ";
  1527. pad2 = ";!";
  1528. break;
  1529. }
  1530. tor_snprintf(buf, sizeof(buf), "%s", pad1);
  1531. tor_snprintf(buf2, sizeof(buf2), "%s", pad2);
  1532. test_assert(NULL == tor_strtok_r_impl(buf, " ", &cp1));
  1533. test_assert(NULL == tor_strtok_r_impl(buf2, ".!..;!", &cp2));
  1534. tor_snprintf(buf, sizeof(buf),
  1535. "%sGraved on the dark in gestures of descent%s", pad1, pad1);
  1536. tor_snprintf(buf2, sizeof(buf2),
  1537. "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2,pad2);
  1538. /* -- "Year's End", Richard Wilbur */
  1539. test_streq("Graved", tor_strtok_r_impl(buf, " ", &cp1));
  1540. test_streq("they", tor_strtok_r_impl(buf2, ".!..;!", &cp2));
  1541. #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
  1542. #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
  1543. test_streq("on", S1());
  1544. test_streq("the", S1());
  1545. test_streq("dark", S1());
  1546. test_streq("seemed", S2());
  1547. test_streq("their", S2());
  1548. test_streq("own", S2());
  1549. test_streq("in", S1());
  1550. test_streq("gestures", S1());
  1551. test_streq("of", S1());
  1552. test_streq("most", S2());
  1553. test_streq("perfect", S2());
  1554. test_streq("descent", S1());
  1555. test_streq("monument", S2());
  1556. test_eq_ptr(NULL, S1());
  1557. test_eq_ptr(NULL, S2());
  1558. }
  1559. buf[0] = 0;
  1560. test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
  1561. test_eq_ptr(NULL, tor_strtok_r_impl(buf, "!", &cp1));
  1562. strlcpy(buf, "Howdy!", sizeof(buf));
  1563. test_streq("Howdy", tor_strtok_r_impl(buf, "!", &cp1));
  1564. test_eq_ptr(NULL, tor_strtok_r_impl(NULL, "!", &cp1));
  1565. strlcpy(buf, " ", sizeof(buf));
  1566. test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
  1567. strlcpy(buf, " ", sizeof(buf));
  1568. test_eq_ptr(NULL, tor_strtok_r_impl(buf, " ", &cp1));
  1569. strlcpy(buf, "something ", sizeof(buf));
  1570. test_streq("something", tor_strtok_r_impl(buf, " ", &cp1));
  1571. test_eq_ptr(NULL, tor_strtok_r_impl(NULL, ";", &cp1));
  1572. done:
  1573. ;
  1574. }
  1575. static void
  1576. test_util_find_str_at_start_of_line(void *ptr)
  1577. {
  1578. const char *long_string =
  1579. "howdy world. how are you? i hope it's fine.\n"
  1580. "hello kitty\n"
  1581. "third line";
  1582. char *line2 = strchr(long_string,'\n')+1;
  1583. char *line3 = strchr(line2,'\n')+1;
  1584. const char *short_string = "hello kitty\n"
  1585. "second line\n";
  1586. char *short_line2 = strchr(short_string,'\n')+1;
  1587. (void)ptr;
  1588. test_eq_ptr(long_string, find_str_at_start_of_line(long_string, ""));
  1589. test_eq_ptr(NULL, find_str_at_start_of_line(short_string, "nonsense"));
  1590. test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "nonsense"));
  1591. test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "\n"));
  1592. test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "how "));
  1593. test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "kitty"));
  1594. test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "h"));
  1595. test_eq_ptr(long_string, find_str_at_start_of_line(long_string, "how"));
  1596. test_eq_ptr(line2, find_str_at_start_of_line(long_string, "he"));
  1597. test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hell"));
  1598. test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello k"));
  1599. test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello kitty\n"));
  1600. test_eq_ptr(line2, find_str_at_start_of_line(long_string, "hello kitty\nt"));
  1601. test_eq_ptr(line3, find_str_at_start_of_line(long_string, "third"));
  1602. test_eq_ptr(line3, find_str_at_start_of_line(long_string, "third line"));
  1603. test_eq_ptr(NULL, find_str_at_start_of_line(long_string, "third line\n"));
  1604. test_eq_ptr(short_line2, find_str_at_start_of_line(short_string,
  1605. "second line\n"));
  1606. done:
  1607. ;
  1608. }
  1609. static void
  1610. test_util_string_is_C_identifier(void *ptr)
  1611. {
  1612. (void)ptr;
  1613. test_eq(1, string_is_C_identifier("string_is_C_identifier"));
  1614. test_eq(1, string_is_C_identifier("_string_is_C_identifier"));
  1615. test_eq(1, string_is_C_identifier("_"));
  1616. test_eq(1, string_is_C_identifier("i"));
  1617. test_eq(1, string_is_C_identifier("_____"));
  1618. test_eq(1, string_is_C_identifier("__00__"));
  1619. test_eq(1, string_is_C_identifier("__init__"));
  1620. test_eq(1, string_is_C_identifier("_0"));
  1621. test_eq(1, string_is_C_identifier("_0string_is_C_identifier"));
  1622. test_eq(1, string_is_C_identifier("_0"));
  1623. test_eq(0, string_is_C_identifier("0_string_is_C_identifier"));
  1624. test_eq(0, string_is_C_identifier("0"));
  1625. test_eq(0, string_is_C_identifier(""));
  1626. test_eq(0, string_is_C_identifier(";"));
  1627. test_eq(0, string_is_C_identifier("i;"));
  1628. test_eq(0, string_is_C_identifier("_;"));
  1629. test_eq(0, string_is_C_identifier("í"));
  1630. test_eq(0, string_is_C_identifier("ñ"));
  1631. done:
  1632. ;
  1633. }
  1634. static void
  1635. test_util_asprintf(void *ptr)
  1636. {
  1637. #define LOREMIPSUM \
  1638. "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
  1639. char *cp=NULL, *cp2=NULL;
  1640. int r;
  1641. (void)ptr;
  1642. /* simple string */
  1643. r = tor_asprintf(&cp, "simple string 100%% safe");
  1644. test_assert(cp);
  1645. test_streq("simple string 100% safe", cp);
  1646. test_eq(strlen(cp), r);
  1647. /* empty string */
  1648. r = tor_asprintf(&cp, "%s", "");
  1649. test_assert(cp);
  1650. test_streq("", cp);
  1651. test_eq(strlen(cp), r);
  1652. /* numbers (%i) */
  1653. r = tor_asprintf(&cp, "I like numbers-%2i, %i, etc.", -1, 2);
  1654. test_assert(cp);
  1655. test_streq("I like numbers--1, 2, etc.", cp);
  1656. test_eq(strlen(cp), r);
  1657. /* numbers (%d) */
  1658. r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202);
  1659. test_assert(cp2);
  1660. test_eq(strlen(cp2), r);
  1661. test_streq("First=101, Second=202", cp2);
  1662. test_assert(cp != cp2);
  1663. tor_free(cp);
  1664. tor_free(cp2);
  1665. /* Glass-box test: a string exactly 128 characters long. */
  1666. r = tor_asprintf(&cp, "Lorem1: %sLorem2: %s", LOREMIPSUM, LOREMIPSUM);
  1667. test_assert(cp);
  1668. test_eq(128, r);
  1669. test_assert(cp[128] == '\0');
  1670. test_streq("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM, cp);
  1671. tor_free(cp);
  1672. /* String longer than 128 characters */
  1673. r = tor_asprintf(&cp, "1: %s 2: %s 3: %s",
  1674. LOREMIPSUM, LOREMIPSUM, LOREMIPSUM);
  1675. test_assert(cp);
  1676. test_eq(strlen(cp), r);
  1677. test_streq("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM, cp);
  1678. done:
  1679. tor_free(cp);
  1680. tor_free(cp2);
  1681. }
  1682. static void
  1683. test_util_listdir(void *ptr)
  1684. {
  1685. smartlist_t *dir_contents = NULL;
  1686. char *fname1=NULL, *fname2=NULL, *fname3=NULL, *dir1=NULL, *dirname=NULL;
  1687. int r;
  1688. (void)ptr;
  1689. fname1 = tor_strdup(get_fname("hopscotch"));
  1690. fname2 = tor_strdup(get_fname("mumblety-peg"));
  1691. fname3 = tor_strdup(get_fname(".hidden-file"));
  1692. dir1 = tor_strdup(get_fname("some-directory"));
  1693. dirname = tor_strdup(get_fname(NULL));
  1694. test_eq(0, write_str_to_file(fname1, "X\n", 0));
  1695. test_eq(0, write_str_to_file(fname2, "Y\n", 0));
  1696. test_eq(0, write_str_to_file(fname3, "Z\n", 0));
  1697. #ifdef _WIN32
  1698. r = mkdir(dir1);
  1699. #else
  1700. r = mkdir(dir1, 0700);
  1701. #endif
  1702. if (r) {
  1703. fprintf(stderr, "Can't create directory %s:", dir1);
  1704. perror("");
  1705. exit(1);
  1706. }
  1707. dir_contents = tor_listdir(dirname);
  1708. test_assert(dir_contents);
  1709. /* make sure that each filename is listed. */
  1710. test_assert(smartlist_string_isin_case(dir_contents, "hopscotch"));
  1711. test_assert(smartlist_string_isin_case(dir_contents, "mumblety-peg"));
  1712. test_assert(smartlist_string_isin_case(dir_contents, ".hidden-file"));
  1713. test_assert(smartlist_string_isin_case(dir_contents, "some-directory"));
  1714. test_assert(!smartlist_string_isin(dir_contents, "."));
  1715. test_assert(!smartlist_string_isin(dir_contents, ".."));
  1716. done:
  1717. tor_free(fname1);
  1718. tor_free(fname2);
  1719. tor_free(dirname);
  1720. if (dir_contents) {
  1721. SMARTLIST_FOREACH(dir_contents, char *, cp, tor_free(cp));
  1722. smartlist_free(dir_contents);
  1723. }
  1724. }
  1725. static void
  1726. test_util_parent_dir(void *ptr)
  1727. {
  1728. char *cp;
  1729. (void)ptr;
  1730. #define T(output,expect_ok,input) \
  1731. do { \
  1732. int ok; \
  1733. cp = tor_strdup(input); \
  1734. ok = get_parent_directory(cp); \
  1735. tt_int_op(expect_ok, ==, ok); \
  1736. if (ok==0) \
  1737. tt_str_op(output, ==, cp); \
  1738. tor_free(cp); \
  1739. } while (0);
  1740. T("/home/wombat", 0, "/home/wombat/knish");
  1741. T("/home/wombat", 0, "/home/wombat/knish/");
  1742. T("/home/wombat", 0, "/home/wombat/knish///");
  1743. T("./home/wombat", 0, "./home/wombat/knish/");
  1744. #if 0
  1745. T("/", 0, "/home");
  1746. T("/", 0, "/home//");
  1747. #endif
  1748. T(".", 0, "./wombat");
  1749. T(".", 0, "./wombat/");
  1750. T(".", 0, "./wombat//");
  1751. T("wombat", 0, "wombat/foo");
  1752. T("wombat/..", 0, "wombat/../foo");
  1753. T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
  1754. T("wombat/.", 0, "wombat/./foo");
  1755. T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
  1756. T("wombat", 0, "wombat/..//");
  1757. T("wombat", 0, "wombat/foo/");
  1758. T("wombat", 0, "wombat/.foo");
  1759. T("wombat", 0, "wombat/.foo/");
  1760. T("", -1, "");
  1761. T("", -1, ".");
  1762. T("", -1, "..");
  1763. T("", -1, "../");
  1764. T("", -1, "/");
  1765. T("", -1, "////");
  1766. T("", -1, "wombat");
  1767. T("", -1, "wombat/");
  1768. done:
  1769. tor_free(cp);
  1770. }
  1771. #ifdef _WIN32
  1772. static void
  1773. test_util_load_win_lib(void *ptr)
  1774. {
  1775. HANDLE h = load_windows_system_library("advapi32.dll");
  1776. (void) ptr;
  1777. tt_assert(h);
  1778. done:
  1779. if (h)
  1780. CloseHandle(h);
  1781. }
  1782. #endif
  1783. static void
  1784. clear_hex_errno(char *hex_errno)
  1785. {
  1786. memset(hex_errno, '\0', HEX_ERRNO_SIZE + 1);
  1787. }
  1788. static void
  1789. test_util_exit_status(void *ptr)
  1790. {
  1791. /* Leave an extra byte for a \0 so we can do string comparison */
  1792. char hex_errno[HEX_ERRNO_SIZE + 1];
  1793. (void)ptr;
  1794. clear_hex_errno(hex_errno);
  1795. format_helper_exit_status(0, 0, hex_errno);
  1796. test_streq(" 0/0\n", hex_errno);
  1797. clear_hex_errno(hex_errno);
  1798. format_helper_exit_status(0, 0x7FFFFFFF, hex_errno);
  1799. test_streq(" 0/7FFFFFFF\n", hex_errno);
  1800. clear_hex_errno(hex_errno);
  1801. format_helper_exit_status(0xFF, -0x80000000, hex_errno);
  1802. test_streq("FF/-80000000\n", hex_errno);
  1803. clear_hex_errno(hex_errno);
  1804. format_helper_exit_status(0x7F, 0, hex_errno);
  1805. test_streq(" 7F/0\n", hex_errno);
  1806. clear_hex_errno(hex_errno);
  1807. format_helper_exit_status(0x08, -0x242, hex_errno);
  1808. test_streq(" 8/-242\n", hex_errno);
  1809. done:
  1810. ;
  1811. }
  1812. #ifndef _WIN32
  1813. /** Check that fgets waits until a full line, and not return a partial line, on
  1814. * a EAGAIN with a non-blocking pipe */
  1815. static void
  1816. test_util_fgets_eagain(void *ptr)
  1817. {
  1818. int test_pipe[2] = {-1, -1};
  1819. int retval;
  1820. ssize_t retlen;
  1821. char *retptr;
  1822. FILE *test_stream = NULL;
  1823. char buf[10];
  1824. (void)ptr;
  1825. /* Set up a pipe to test on */
  1826. retval = pipe(test_pipe);
  1827. tt_int_op(retval, >=, 0);
  1828. /* Set up the read-end to be non-blocking */
  1829. retval = fcntl(test_pipe[0], F_SETFL, O_NONBLOCK);
  1830. tt_int_op(retval, >=, 0);
  1831. /* Open it as a stdio stream */
  1832. test_stream = fdopen(test_pipe[0], "r");
  1833. tt_ptr_op(test_stream, !=, NULL);
  1834. /* Send in a partial line */
  1835. retlen = write(test_pipe[1], "A", 1);
  1836. tt_int_op(retlen, ==, 1);
  1837. retptr = fgets(buf, sizeof(buf), test_stream);
  1838. tt_want(retptr == NULL);
  1839. tt_int_op(errno, ==, EAGAIN);
  1840. /* Send in the rest */
  1841. retlen = write(test_pipe[1], "B\n", 2);
  1842. tt_int_op(retlen, ==, 2);
  1843. retptr = fgets(buf, sizeof(buf), test_stream);
  1844. tt_ptr_op(retptr, ==, buf);
  1845. tt_str_op(buf, ==, "AB\n");
  1846. /* Send in a full line */
  1847. retlen = write(test_pipe[1], "CD\n", 3);
  1848. tt_int_op(retlen, ==, 3);
  1849. retptr = fgets(buf, sizeof(buf), test_stream);
  1850. tt_ptr_op(retptr, ==, buf);
  1851. tt_str_op(buf, ==, "CD\n");
  1852. /* Send in a partial line */
  1853. retlen = write(test_pipe[1], "E", 1);
  1854. tt_int_op(retlen, ==, 1);
  1855. retptr = fgets(buf, sizeof(buf), test_stream);
  1856. tt_ptr_op(retptr, ==, NULL);
  1857. tt_int_op(errno, ==, EAGAIN);
  1858. /* Send in the rest */
  1859. retlen = write(test_pipe[1], "F\n", 2);
  1860. tt_int_op(retlen, ==, 2);
  1861. retptr = fgets(buf, sizeof(buf), test_stream);
  1862. tt_ptr_op(retptr, ==, buf);
  1863. tt_str_op(buf, ==, "EF\n");
  1864. /* Send in a full line and close */
  1865. retlen = write(test_pipe[1], "GH", 2);
  1866. tt_int_op(retlen, ==, 2);
  1867. retval = close(test_pipe[1]);
  1868. test_pipe[1] = -1;
  1869. tt_int_op(retval, ==, 0);
  1870. retptr = fgets(buf, sizeof(buf), test_stream);
  1871. tt_ptr_op(retptr, ==, buf);
  1872. tt_str_op(buf, ==, "GH");
  1873. /* Check for EOF */
  1874. retptr = fgets(buf, sizeof(buf), test_stream);
  1875. tt_ptr_op(retptr, ==, NULL);
  1876. tt_int_op(feof(test_stream), >, 0);
  1877. done:
  1878. if (test_stream != NULL)
  1879. fclose(test_stream);
  1880. if (test_pipe[0] != -1)
  1881. close(test_pipe[0]);
  1882. if (test_pipe[1] != -1)
  1883. close(test_pipe[1]);
  1884. }
  1885. #endif
  1886. /** Helper function for testing tor_spawn_background */
  1887. static void
  1888. run_util_spawn_background(const char *argv[], const char *expected_out,
  1889. const char *expected_err, int expected_exit,
  1890. int expected_status)
  1891. {
  1892. int retval, exit_code;
  1893. ssize_t pos;
  1894. process_handle_t *process_handle=NULL;
  1895. char stdout_buf[100], stderr_buf[100];
  1896. int status;
  1897. /* Start the program */
  1898. #ifdef _WIN32
  1899. status = tor_spawn_background(NULL, argv, NULL, &process_handle);
  1900. #else
  1901. status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
  1902. #endif
  1903. test_eq(expected_status, status);
  1904. if (status == PROCESS_STATUS_ERROR)
  1905. return;
  1906. test_assert(process_handle != NULL);
  1907. test_eq(expected_status, process_handle->status);
  1908. test_assert(process_handle->stdout_pipe > 0);
  1909. test_assert(process_handle->stderr_pipe > 0);
  1910. /* Check stdout */
  1911. pos = tor_read_all_from_process_stdout(process_handle, stdout_buf,
  1912. sizeof(stdout_buf) - 1);
  1913. tt_assert(pos >= 0);
  1914. stdout_buf[pos] = '\0';
  1915. test_eq(strlen(expected_out), pos);
  1916. test_streq(expected_out, stdout_buf);
  1917. /* Check it terminated correctly */
  1918. retval = tor_get_exit_code(process_handle, 1, &exit_code);
  1919. test_eq(PROCESS_EXIT_EXITED, retval);
  1920. test_eq(expected_exit, exit_code);
  1921. // TODO: Make test-child exit with something other than 0
  1922. /* Check stderr */
  1923. pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
  1924. sizeof(stderr_buf) - 1);
  1925. test_assert(pos >= 0);
  1926. stderr_buf[pos] = '\0';
  1927. test_streq(expected_err, stderr_buf);
  1928. test_eq(strlen(expected_err), pos);
  1929. done:
  1930. if (process_handle)
  1931. tor_process_handle_destroy(process_handle, 1);
  1932. }
  1933. /** Check that we can launch a process and read the output */
  1934. static void
  1935. test_util_spawn_background_ok(void *ptr)
  1936. {
  1937. #ifdef _WIN32
  1938. const char *argv[] = {"test-child.exe", "--test", NULL};
  1939. const char *expected_out = "OUT\r\n--test\r\nSLEEPING\r\nDONE\r\n";
  1940. const char *expected_err = "ERR\r\n";
  1941. #else
  1942. const char *argv[] = {BUILDDIR "/src/test/test-child", "--test", NULL};
  1943. const char *expected_out = "OUT\n--test\nSLEEPING\nDONE\n";
  1944. const char *expected_err = "ERR\n";
  1945. #endif
  1946. (void)ptr;
  1947. run_util_spawn_background(argv, expected_out, expected_err, 0,
  1948. PROCESS_STATUS_RUNNING);
  1949. }
  1950. /** Check that failing to find the executable works as expected */
  1951. static void
  1952. test_util_spawn_background_fail(void *ptr)
  1953. {
  1954. #ifndef BUILDDIR
  1955. #define BUILDDIR "."
  1956. #endif
  1957. const char *argv[] = {BUILDDIR "/src/test/no-such-file", "--test", NULL};
  1958. const char *expected_err = "";
  1959. char expected_out[1024];
  1960. char code[32];
  1961. #ifdef _WIN32
  1962. const int expected_status = PROCESS_STATUS_ERROR;
  1963. #else
  1964. /* TODO: Once we can signal failure to exec, set this to be
  1965. * PROCESS_STATUS_ERROR */
  1966. const int expected_status = PROCESS_STATUS_RUNNING;
  1967. #endif
  1968. (void)ptr;
  1969. tor_snprintf(code, sizeof(code), "%x/%x",
  1970. 9 /* CHILD_STATE_FAILEXEC */ , ENOENT);
  1971. tor_snprintf(expected_out, sizeof(expected_out),
  1972. "ERR: Failed to spawn background process - code %12s\n", code);
  1973. run_util_spawn_background(argv, expected_out, expected_err, 255,
  1974. expected_status);
  1975. }
  1976. /** Test that reading from a handle returns a partial read rather than
  1977. * blocking */
  1978. static void
  1979. test_util_spawn_background_partial_read(void *ptr)
  1980. {
  1981. const int expected_exit = 0;
  1982. const int expected_status = PROCESS_STATUS_RUNNING;
  1983. int retval, exit_code;
  1984. ssize_t pos = -1;
  1985. process_handle_t *process_handle=NULL;
  1986. int status;
  1987. char stdout_buf[100], stderr_buf[100];
  1988. #ifdef _WIN32
  1989. const char *argv[] = {"test-child.exe", "--test", NULL};
  1990. const char *expected_out[] = { "OUT\r\n--test\r\nSLEEPING\r\n",
  1991. "DONE\r\n",
  1992. NULL };
  1993. const char *expected_err = "ERR\r\n";
  1994. #else
  1995. const char *argv[] = {BUILDDIR "/src/test/test-child", "--test", NULL};
  1996. const char *expected_out[] = { "OUT\n--test\nSLEEPING\n",
  1997. "DONE\n",
  1998. NULL };
  1999. const char *expected_err = "ERR\n";
  2000. int eof = 0;
  2001. #endif
  2002. int expected_out_ctr;
  2003. (void)ptr;
  2004. /* Start the program */
  2005. #ifdef _WIN32
  2006. status = tor_spawn_background(NULL, argv, NULL, &process_handle);
  2007. #else
  2008. status = tor_spawn_background(argv[0], argv, NULL, &process_handle);
  2009. #endif
  2010. test_eq(expected_status, status);
  2011. test_assert(process_handle);
  2012. test_eq(expected_status, process_handle->status);
  2013. /* Check stdout */
  2014. for (expected_out_ctr = 0; expected_out[expected_out_ctr] != NULL;) {
  2015. #ifdef _WIN32
  2016. pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
  2017. sizeof(stdout_buf) - 1, NULL);
  2018. #else
  2019. /* Check that we didn't read the end of file last time */
  2020. test_assert(!eof);
  2021. pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
  2022. sizeof(stdout_buf) - 1, NULL, &eof);
  2023. #endif
  2024. log_info(LD_GENERAL, "tor_read_all_handle() returned %d", (int)pos);
  2025. /* We would have blocked, keep on trying */
  2026. if (0 == pos)
  2027. continue;
  2028. test_assert(pos > 0);
  2029. stdout_buf[pos] = '\0';
  2030. test_streq(expected_out[expected_out_ctr], stdout_buf);
  2031. test_eq(strlen(expected_out[expected_out_ctr]), pos);
  2032. expected_out_ctr++;
  2033. }
  2034. /* The process should have exited without writing more */
  2035. #ifdef _WIN32
  2036. pos = tor_read_all_handle(process_handle->stdout_pipe, stdout_buf,
  2037. sizeof(stdout_buf) - 1,
  2038. process_handle);
  2039. test_eq(0, pos);
  2040. #else
  2041. if (!eof) {
  2042. /* We should have got all the data, but maybe not the EOF flag */
  2043. pos = tor_read_all_handle(process_handle->stdout_handle, stdout_buf,
  2044. sizeof(stdout_buf) - 1,
  2045. process_handle, &eof);
  2046. test_eq(0, pos);
  2047. test_assert(eof);
  2048. }
  2049. /* Otherwise, we got the EOF on the last read */
  2050. #endif
  2051. /* Check it terminated correctly */
  2052. retval = tor_get_exit_code(process_handle, 1, &exit_code);
  2053. test_eq(PROCESS_EXIT_EXITED, retval);
  2054. test_eq(expected_exit, exit_code);
  2055. // TODO: Make test-child exit with something other than 0
  2056. /* Check stderr */
  2057. pos = tor_read_all_from_process_stderr(process_handle, stderr_buf,
  2058. sizeof(stderr_buf) - 1);
  2059. test_assert(pos >= 0);
  2060. stderr_buf[pos] = '\0';
  2061. test_streq(expected_err, stderr_buf);
  2062. test_eq(strlen(expected_err), pos);
  2063. done:
  2064. tor_process_handle_destroy(process_handle, 1);
  2065. }
  2066. /**
  2067. * Test that we can properly format q Windows command line
  2068. */
  2069. static void
  2070. test_util_join_win_cmdline(void *ptr)
  2071. {
  2072. /* Based on some test cases from "Parsing C++ Command-Line Arguments" in
  2073. * MSDN but we don't exercise all quoting rules because tor_join_win_cmdline
  2074. * will try to only generate simple cases for the child process to parse;
  2075. * i.e. we never embed quoted strings in arguments. */
  2076. const char *argvs[][4] = {
  2077. {"a", "bb", "CCC", NULL}, // Normal
  2078. {NULL, NULL, NULL, NULL}, // Empty argument list
  2079. {"", NULL, NULL, NULL}, // Empty argument
  2080. {"\"a", "b\"b", "CCC\"", NULL}, // Quotes
  2081. {"a\tbc", "dd dd", "E", NULL}, // Whitespace
  2082. {"a\\\\\\b", "de fg", "H", NULL}, // Backslashes
  2083. {"a\\\"b", "\\c", "D\\", NULL}, // Backslashes before quote
  2084. {"a\\\\b c", "d", "E", NULL}, // Backslashes not before quote
  2085. { NULL } // Terminator
  2086. };
  2087. const char *cmdlines[] = {
  2088. "a bb CCC",
  2089. "",
  2090. "\"\"",
  2091. "\\\"a b\\\"b CCC\\\"",
  2092. "\"a\tbc\" \"dd dd\" E",
  2093. "a\\\\\\b \"de fg\" H",
  2094. "a\\\\\\\"b \\c D\\",
  2095. "\"a\\\\b c\" d E",
  2096. NULL // Terminator
  2097. };
  2098. int i;
  2099. char *joined_argv;
  2100. (void)ptr;
  2101. for (i=0; cmdlines[i]!=NULL; i++) {
  2102. log_info(LD_GENERAL, "Joining argvs[%d], expecting <%s>", i, cmdlines[i]);
  2103. joined_argv = tor_join_win_cmdline(argvs[i]);
  2104. test_streq(cmdlines[i], joined_argv);
  2105. tor_free(joined_argv);
  2106. }
  2107. done:
  2108. ;
  2109. }
  2110. #define MAX_SPLIT_LINE_COUNT 4
  2111. struct split_lines_test_t {
  2112. const char *orig_line; // Line to be split (may contain \0's)
  2113. int orig_length; // Length of orig_line
  2114. const char *split_line[MAX_SPLIT_LINE_COUNT]; // Split lines
  2115. };
  2116. /**
  2117. * Test that we properly split a buffer into lines
  2118. */
  2119. static void
  2120. test_util_split_lines(void *ptr)
  2121. {
  2122. /* Test cases. orig_line of last test case must be NULL.
  2123. * The last element of split_line[i] must be NULL. */
  2124. struct split_lines_test_t tests[] = {
  2125. {"", 0, {NULL}},
  2126. {"foo", 3, {"foo", NULL}},
  2127. {"\n\rfoo\n\rbar\r\n", 12, {"foo", "bar", NULL}},
  2128. {"fo o\r\nb\tar", 10, {"fo o", "b.ar", NULL}},
  2129. {"\x0f""f\0o\0\n\x01""b\0r\0\r", 12, {".f.o.", ".b.r.", NULL}},
  2130. {"line 1\r\nline 2", 14, {"line 1", "line 2", NULL}},
  2131. {"line 1\r\n\r\nline 2", 16, {"line 1", "line 2", NULL}},
  2132. {"line 1\r\n\r\r\r\nline 2", 18, {"line 1", "line 2", NULL}},
  2133. {"line 1\r\n\n\n\n\rline 2", 18, {"line 1", "line 2", NULL}},
  2134. {"line 1\r\n\r\t\r\nline 3", 18, {"line 1", ".", "line 3", NULL}},
  2135. {"\n\t\r\t\nline 3", 11, {".", ".", "line 3", NULL}},
  2136. {NULL, 0, { NULL }}
  2137. };
  2138. int i, j;
  2139. char *orig_line=NULL;
  2140. smartlist_t *sl=NULL;
  2141. (void)ptr;
  2142. for (i=0; tests[i].orig_line; i++) {
  2143. sl = smartlist_new();
  2144. /* Allocate space for string and trailing NULL */
  2145. orig_line = tor_memdup(tests[i].orig_line, tests[i].orig_length + 1);
  2146. tor_split_lines(sl, orig_line, tests[i].orig_length);
  2147. j = 0;
  2148. log_info(LD_GENERAL, "Splitting test %d of length %d",
  2149. i, tests[i].orig_length);
  2150. SMARTLIST_FOREACH(sl, const char *, line,
  2151. {
  2152. /* Check we have not got too many lines */
  2153. test_assert(j < MAX_SPLIT_LINE_COUNT);
  2154. /* Check that there actually should be a line here */
  2155. test_assert(tests[i].split_line[j] != NULL);
  2156. log_info(LD_GENERAL, "Line %d of test %d, should be <%s>",
  2157. j, i, tests[i].split_line[j]);
  2158. /* Check that the line is as expected */
  2159. test_streq(line, tests[i].split_line[j]);
  2160. j++;
  2161. });
  2162. /* Check that we didn't miss some lines */
  2163. test_eq_ptr(NULL, tests[i].split_line[j]);
  2164. tor_free(orig_line);
  2165. smartlist_free(sl);
  2166. sl = NULL;
  2167. }
  2168. done:
  2169. tor_free(orig_line);
  2170. smartlist_free(sl);
  2171. }
  2172. static void
  2173. test_util_di_ops(void)
  2174. {
  2175. #define LT -1
  2176. #define GT 1
  2177. #define EQ 0
  2178. const struct {
  2179. const char *a; int want_sign; const char *b;
  2180. } examples[] = {
  2181. { "Foo", EQ, "Foo" },
  2182. { "foo", GT, "bar", },
  2183. { "foobar", EQ ,"foobar" },
  2184. { "foobar", LT, "foobaw" },
  2185. { "foobar", GT, "f00bar" },
  2186. { "foobar", GT, "boobar" },
  2187. { "", EQ, "" },
  2188. { NULL, 0, NULL },
  2189. };
  2190. int i;
  2191. for (i = 0; examples[i].a; ++i) {
  2192. size_t len = strlen(examples[i].a);
  2193. int eq1, eq2, neq1, neq2, cmp1, cmp2;
  2194. test_eq(len, strlen(examples[i].b));
  2195. /* We do all of the operations, with operands in both orders. */
  2196. eq1 = tor_memeq(examples[i].a, examples[i].b, len);
  2197. eq2 = tor_memeq(examples[i].b, examples[i].a, len);
  2198. neq1 = tor_memneq(examples[i].a, examples[i].b, len);
  2199. neq2 = tor_memneq(examples[i].b, examples[i].a, len);
  2200. cmp1 = tor_memcmp(examples[i].a, examples[i].b, len);
  2201. cmp2 = tor_memcmp(examples[i].b, examples[i].a, len);
  2202. /* Check for correctness of cmp1 */
  2203. if (cmp1 < 0 && examples[i].want_sign != LT)
  2204. test_fail();
  2205. else if (cmp1 > 0 && examples[i].want_sign != GT)
  2206. test_fail();
  2207. else if (cmp1 == 0 && examples[i].want_sign != EQ)
  2208. test_fail();
  2209. /* Check for consistency of everything else with cmp1 */
  2210. test_eq(eq1, eq2);
  2211. test_eq(neq1, neq2);
  2212. test_eq(cmp1, -cmp2);
  2213. test_eq(eq1, cmp1 == 0);
  2214. test_eq(neq1, !eq1);
  2215. }
  2216. done:
  2217. ;
  2218. }
  2219. /**
  2220. * Test counting high bits
  2221. */
  2222. static void
  2223. test_util_n_bits_set(void *ptr)
  2224. {
  2225. (void)ptr;
  2226. test_eq(0, n_bits_set_u8(0));
  2227. test_eq(1, n_bits_set_u8(1));
  2228. test_eq(3, n_bits_set_u8(7));
  2229. test_eq(1, n_bits_set_u8(8));
  2230. test_eq(2, n_bits_set_u8(129));
  2231. test_eq(8, n_bits_set_u8(255));
  2232. done:
  2233. ;
  2234. }
  2235. /**
  2236. * Test LHS whitespace (and comment) eater
  2237. */
  2238. static void
  2239. test_util_eat_whitespace(void *ptr)
  2240. {
  2241. const char ws[] = { ' ', '\t', '\r' }; /* Except NL */
  2242. char str[80];
  2243. size_t i;
  2244. (void)ptr;
  2245. /* Try one leading ws */
  2246. strcpy(str, "fuubaar");
  2247. for (i = 0; i < sizeof(ws); ++i) {
  2248. str[0] = ws[i];
  2249. test_eq_ptr(str + 1, eat_whitespace(str));
  2250. test_eq_ptr(str + 1, eat_whitespace_eos(str, str + strlen(str)));
  2251. test_eq_ptr(str + 1, eat_whitespace_no_nl(str));
  2252. test_eq_ptr(str + 1, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2253. }
  2254. str[0] = '\n';
  2255. test_eq_ptr(str + 1, eat_whitespace(str));
  2256. test_eq_ptr(str + 1, eat_whitespace_eos(str, str + strlen(str)));
  2257. test_eq_ptr(str, eat_whitespace_no_nl(str));
  2258. test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2259. /* Empty string */
  2260. strcpy(str, "");
  2261. test_eq_ptr(str, eat_whitespace(str));
  2262. test_eq_ptr(str, eat_whitespace_eos(str, str));
  2263. test_eq_ptr(str, eat_whitespace_no_nl(str));
  2264. test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str));
  2265. /* Only ws */
  2266. strcpy(str, " \t\r\n");
  2267. test_eq_ptr(str + strlen(str), eat_whitespace(str));
  2268. test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
  2269. test_eq_ptr(str + strlen(str) - 1,
  2270. eat_whitespace_no_nl(str));
  2271. test_eq_ptr(str + strlen(str) - 1,
  2272. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2273. strcpy(str, " \t\r ");
  2274. test_eq_ptr(str + strlen(str), eat_whitespace(str));
  2275. test_eq_ptr(str + strlen(str),
  2276. eat_whitespace_eos(str, str + strlen(str)));
  2277. test_eq_ptr(str + strlen(str), eat_whitespace_no_nl(str));
  2278. test_eq_ptr(str + strlen(str),
  2279. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2280. /* Multiple ws */
  2281. strcpy(str, "fuubaar");
  2282. for (i = 0; i < sizeof(ws); ++i)
  2283. str[i] = ws[i];
  2284. test_eq_ptr(str + sizeof(ws), eat_whitespace(str));
  2285. test_eq_ptr(str + sizeof(ws), eat_whitespace_eos(str, str + strlen(str)));
  2286. test_eq_ptr(str + sizeof(ws), eat_whitespace_no_nl(str));
  2287. test_eq_ptr(str + sizeof(ws),
  2288. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2289. /* Eat comment */
  2290. strcpy(str, "# Comment \n No Comment");
  2291. test_streq("No Comment", eat_whitespace(str));
  2292. test_streq("No Comment", eat_whitespace_eos(str, str + strlen(str)));
  2293. test_eq_ptr(str, eat_whitespace_no_nl(str));
  2294. test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2295. /* Eat comment & ws mix */
  2296. strcpy(str, " # \t Comment \n\t\nNo Comment");
  2297. test_streq("No Comment", eat_whitespace(str));
  2298. test_streq("No Comment", eat_whitespace_eos(str, str + strlen(str)));
  2299. test_eq_ptr(str + 1, eat_whitespace_no_nl(str));
  2300. test_eq_ptr(str + 1, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2301. /* Eat entire comment */
  2302. strcpy(str, "#Comment");
  2303. test_eq_ptr(str + strlen(str), eat_whitespace(str));
  2304. test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
  2305. test_eq_ptr(str, eat_whitespace_no_nl(str));
  2306. test_eq_ptr(str, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2307. /* Blank line, then comment */
  2308. strcpy(str, " \t\n # Comment");
  2309. test_eq_ptr(str + strlen(str), eat_whitespace(str));
  2310. test_eq_ptr(str + strlen(str), eat_whitespace_eos(str, str + strlen(str)));
  2311. test_eq_ptr(str + 2, eat_whitespace_no_nl(str));
  2312. test_eq_ptr(str + 2, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  2313. done:
  2314. ;
  2315. }
  2316. /** Return a newly allocated smartlist containing the lines of text in
  2317. * <b>lines</b>. The returned strings are heap-allocated, and must be
  2318. * freed by the caller.
  2319. *
  2320. * XXXX? Move to container.[hc] ? */
  2321. static smartlist_t *
  2322. smartlist_new_from_text_lines(const char *lines)
  2323. {
  2324. smartlist_t *sl = smartlist_new();
  2325. char *last_line;
  2326. smartlist_split_string(sl, lines, "\n", 0, 0);
  2327. last_line = smartlist_pop_last(sl);
  2328. if (last_line != NULL && *last_line != '\0') {
  2329. smartlist_add(sl, last_line);
  2330. }
  2331. return sl;
  2332. }
  2333. /** Test smartlist_new_from_text_lines */
  2334. static void
  2335. test_util_sl_new_from_text_lines(void *ptr)
  2336. {
  2337. (void)ptr;
  2338. { /* Normal usage */
  2339. smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz\n");
  2340. int sl_len = smartlist_len(sl);
  2341. tt_want_int_op(sl_len, ==, 3);
  2342. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), ==, "foo");
  2343. if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), ==, "bar");
  2344. if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), ==, "baz");
  2345. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  2346. smartlist_free(sl);
  2347. }
  2348. { /* No final newline */
  2349. smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz");
  2350. int sl_len = smartlist_len(sl);
  2351. tt_want_int_op(sl_len, ==, 3);
  2352. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), ==, "foo");
  2353. if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), ==, "bar");
  2354. if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), ==, "baz");
  2355. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  2356. smartlist_free(sl);
  2357. }
  2358. { /* No newlines */
  2359. smartlist_t *sl = smartlist_new_from_text_lines("foo");
  2360. int sl_len = smartlist_len(sl);
  2361. tt_want_int_op(sl_len, ==, 1);
  2362. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), ==, "foo");
  2363. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  2364. smartlist_free(sl);
  2365. }
  2366. { /* No text at all */
  2367. smartlist_t *sl = smartlist_new_from_text_lines("");
  2368. int sl_len = smartlist_len(sl);
  2369. tt_want_int_op(sl_len, ==, 0);
  2370. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  2371. smartlist_free(sl);
  2372. }
  2373. }
  2374. /** Test process_environment_make */
  2375. static void
  2376. test_util_make_environment(void *ptr)
  2377. {
  2378. const char *env_vars_string =
  2379. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  2380. "HOME=/home/foozer\n";
  2381. const char expected_windows_env_block[] =
  2382. "HOME=/home/foozer\000"
  2383. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
  2384. "\000";
  2385. size_t expected_windows_env_block_len =
  2386. sizeof(expected_windows_env_block) - 1;
  2387. smartlist_t *env_vars = smartlist_new_from_text_lines(env_vars_string);
  2388. smartlist_t *env_vars_sorted = smartlist_new();
  2389. smartlist_t *env_vars_in_unixoid_env_block_sorted = smartlist_new();
  2390. process_environment_t *env;
  2391. (void)ptr;
  2392. env = process_environment_make(env_vars);
  2393. /* Check that the Windows environment block is correct. */
  2394. tt_want(tor_memeq(expected_windows_env_block, env->windows_environment_block,
  2395. expected_windows_env_block_len));
  2396. /* Now for the Unixoid environment block. We don't care which order
  2397. * these environment variables are in, so we sort both lists first. */
  2398. smartlist_add_all(env_vars_sorted, env_vars);
  2399. {
  2400. char **v;
  2401. for (v = env->unixoid_environment_block; *v; ++v) {
  2402. smartlist_add(env_vars_in_unixoid_env_block_sorted, *v);
  2403. }
  2404. }
  2405. smartlist_sort_strings(env_vars_sorted);
  2406. smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted);
  2407. tt_want_int_op(smartlist_len(env_vars_sorted), ==,
  2408. smartlist_len(env_vars_in_unixoid_env_block_sorted));
  2409. {
  2410. int len = smartlist_len(env_vars_sorted);
  2411. int i;
  2412. if (smartlist_len(env_vars_in_unixoid_env_block_sorted) < len) {
  2413. len = smartlist_len(env_vars_in_unixoid_env_block_sorted);
  2414. }
  2415. for (i = 0; i < len; ++i) {
  2416. tt_want_str_op(smartlist_get(env_vars_sorted, i), ==,
  2417. smartlist_get(env_vars_in_unixoid_env_block_sorted, i));
  2418. }
  2419. }
  2420. /* Clean up. */
  2421. smartlist_free(env_vars_in_unixoid_env_block_sorted);
  2422. smartlist_free(env_vars_sorted);
  2423. SMARTLIST_FOREACH(env_vars, char *, x, tor_free(x));
  2424. smartlist_free(env_vars);
  2425. process_environment_free(env);
  2426. }
  2427. /** Test set_environment_variable_in_smartlist */
  2428. static void
  2429. test_util_set_env_var_in_sl(void *ptr)
  2430. {
  2431. /* The environment variables in these strings are in arbitrary
  2432. * order; we sort the resulting lists before comparing them.
  2433. *
  2434. * (They *will not* end up in the order shown in
  2435. * expected_resulting_env_vars_string.) */
  2436. const char *base_env_vars_string =
  2437. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  2438. "HOME=/home/foozer\n"
  2439. "TERM=xterm\n"
  2440. "SHELL=/bin/ksh\n"
  2441. "USER=foozer\n"
  2442. "LOGNAME=foozer\n"
  2443. "USERNAME=foozer\n"
  2444. "LANG=en_US.utf8\n"
  2445. ;
  2446. const char *new_env_vars_string =
  2447. "TERM=putty\n"
  2448. "DISPLAY=:18.0\n"
  2449. ;
  2450. const char *expected_resulting_env_vars_string =
  2451. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  2452. "HOME=/home/foozer\n"
  2453. "TERM=putty\n"
  2454. "SHELL=/bin/ksh\n"
  2455. "USER=foozer\n"
  2456. "LOGNAME=foozer\n"
  2457. "USERNAME=foozer\n"
  2458. "LANG=en_US.utf8\n"
  2459. "DISPLAY=:18.0\n"
  2460. ;
  2461. smartlist_t *merged_env_vars =
  2462. smartlist_new_from_text_lines(base_env_vars_string);
  2463. smartlist_t *new_env_vars =
  2464. smartlist_new_from_text_lines(new_env_vars_string);
  2465. smartlist_t *expected_resulting_env_vars =
  2466. smartlist_new_from_text_lines(expected_resulting_env_vars_string);
  2467. /* Elements of merged_env_vars are heap-allocated, and must be
  2468. * freed. Some of them are (or should) be freed by
  2469. * set_environment_variable_in_smartlist.
  2470. *
  2471. * Elements of new_env_vars are heap-allocated, but are copied into
  2472. * merged_env_vars, so they are not freed separately at the end of
  2473. * the function.
  2474. *
  2475. * Elements of expected_resulting_env_vars are heap-allocated, and
  2476. * must be freed. */
  2477. (void)ptr;
  2478. SMARTLIST_FOREACH(new_env_vars, char *, env_var,
  2479. set_environment_variable_in_smartlist(merged_env_vars,
  2480. env_var,
  2481. _tor_free,
  2482. 1));
  2483. smartlist_sort_strings(merged_env_vars);
  2484. smartlist_sort_strings(expected_resulting_env_vars);
  2485. tt_want_int_op(smartlist_len(merged_env_vars), ==,
  2486. smartlist_len(expected_resulting_env_vars));
  2487. {
  2488. int len = smartlist_len(merged_env_vars);
  2489. int i;
  2490. if (smartlist_len(expected_resulting_env_vars) < len) {
  2491. len = smartlist_len(expected_resulting_env_vars);
  2492. }
  2493. for (i = 0; i < len; ++i) {
  2494. tt_want_str_op(smartlist_get(merged_env_vars, i), ==,
  2495. smartlist_get(expected_resulting_env_vars, i));
  2496. }
  2497. }
  2498. /* Clean up. */
  2499. SMARTLIST_FOREACH(merged_env_vars, char *, x, tor_free(x));
  2500. smartlist_free(merged_env_vars);
  2501. smartlist_free(new_env_vars);
  2502. SMARTLIST_FOREACH(expected_resulting_env_vars, char *, x, tor_free(x));
  2503. smartlist_free(expected_resulting_env_vars);
  2504. }
  2505. #define UTIL_LEGACY(name) \
  2506. { #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
  2507. #define UTIL_TEST(name, flags) \
  2508. { #name, test_util_ ## name, flags, NULL, NULL }
  2509. struct testcase_t util_tests[] = {
  2510. UTIL_LEGACY(time),
  2511. UTIL_LEGACY(config_line),
  2512. UTIL_LEGACY(config_line_quotes),
  2513. UTIL_LEGACY(config_line_comment_character),
  2514. UTIL_LEGACY(config_line_escaped_content),
  2515. #ifndef _WIN32
  2516. UTIL_LEGACY(expand_filename),
  2517. #endif
  2518. UTIL_LEGACY(strmisc),
  2519. UTIL_LEGACY(pow2),
  2520. UTIL_LEGACY(gzip),
  2521. UTIL_LEGACY(datadir),
  2522. UTIL_LEGACY(mempool),
  2523. UTIL_LEGACY(memarea),
  2524. UTIL_LEGACY(control_formats),
  2525. UTIL_LEGACY(mmap),
  2526. UTIL_LEGACY(threads),
  2527. UTIL_LEGACY(sscanf),
  2528. UTIL_LEGACY(path_is_relative),
  2529. UTIL_LEGACY(strtok),
  2530. UTIL_LEGACY(di_ops),
  2531. UTIL_TEST(find_str_at_start_of_line, 0),
  2532. UTIL_TEST(string_is_C_identifier, 0),
  2533. UTIL_TEST(asprintf, 0),
  2534. UTIL_TEST(listdir, 0),
  2535. UTIL_TEST(parent_dir, 0),
  2536. #ifdef _WIN32
  2537. UTIL_TEST(load_win_lib, 0),
  2538. #endif
  2539. UTIL_TEST(exit_status, 0),
  2540. #ifndef _WIN32
  2541. UTIL_TEST(fgets_eagain, TT_SKIP),
  2542. #endif
  2543. UTIL_TEST(spawn_background_ok, 0),
  2544. UTIL_TEST(spawn_background_fail, 0),
  2545. UTIL_TEST(spawn_background_partial_read, 0),
  2546. UTIL_TEST(join_win_cmdline, 0),
  2547. UTIL_TEST(split_lines, 0),
  2548. UTIL_TEST(n_bits_set, 0),
  2549. UTIL_TEST(eat_whitespace, 0),
  2550. UTIL_TEST(sl_new_from_text_lines, 0),
  2551. UTIL_TEST(make_environment, 0),
  2552. UTIL_TEST(set_env_var_in_sl, 0),
  2553. END_OF_TESTCASES
  2554. };