test_util.c 198 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #include "orconfig.h"
  6. #define COMPAT_PRIVATE
  7. #define COMPAT_TIME_PRIVATE
  8. #define UTIL_PRIVATE
  9. #define UTIL_MALLOC_PRIVATE
  10. #define SOCKET_PRIVATE
  11. #define PROCESS_WIN32_PRIVATE
  12. #include "lib/testsupport/testsupport.h"
  13. #include "core/or/or.h"
  14. #include "lib/buf/buffers.h"
  15. #include "app/config/config.h"
  16. #include "feature/control/control.h"
  17. #include "feature/control/control_proto.h"
  18. #include "feature/client/transports.h"
  19. #include "lib/crypt_ops/crypto_format.h"
  20. #include "lib/crypt_ops/crypto_rand.h"
  21. #include "lib/defs/time.h"
  22. #include "test/test.h"
  23. #include "lib/memarea/memarea.h"
  24. #include "lib/process/waitpid.h"
  25. #include "lib/process/process_win32.h"
  26. #include "test/log_test_helpers.h"
  27. #include "lib/compress/compress.h"
  28. #include "lib/compress/compress_zstd.h"
  29. #include "lib/encoding/keyval.h"
  30. #include "lib/fdio/fdio.h"
  31. #include "lib/fs/winlib.h"
  32. #include "lib/process/env.h"
  33. #include "lib/process/pidfile.h"
  34. #include "lib/intmath/weakrng.h"
  35. #include "lib/thread/numcpus.h"
  36. #include "lib/math/fp.h"
  37. #include "lib/math/laplace.h"
  38. #include "lib/meminfo/meminfo.h"
  39. #include "lib/time/tvdiff.h"
  40. #include "lib/encoding/confline.h"
  41. #include "lib/net/socketpair.h"
  42. #include "lib/malloc/map_anon.h"
  43. #ifdef HAVE_PWD_H
  44. #include <pwd.h>
  45. #endif
  46. #ifdef HAVE_SYS_UTIME_H
  47. #include <sys/utime.h>
  48. #endif
  49. #ifdef HAVE_UTIME_H
  50. #include <utime.h>
  51. #endif
  52. #ifdef HAVE_SYS_STAT_H
  53. #include <sys/stat.h>
  54. #endif
  55. #ifdef HAVE_FCNTL_H
  56. #include <fcntl.h>
  57. #endif
  58. #ifdef HAVE_UNISTD_H
  59. #include <unistd.h>
  60. #endif
  61. #ifdef HAVE_SYS_MMAN_H
  62. #include <sys/mman.h>
  63. #endif
  64. #ifdef HAVE_SYS_WAIT_H
  65. #include <sys/wait.h>
  66. #endif
  67. #ifdef _WIN32
  68. #include <tchar.h>
  69. #endif
  70. #include <math.h>
  71. #include <ctype.h>
  72. #include <float.h>
  73. #define INFINITY_DBL ((double)INFINITY)
  74. #define NAN_DBL ((double)NAN)
  75. /** Test the tor_isinf() wrapper */
  76. static void
  77. test_tor_isinf(void *arg)
  78. {
  79. (void) arg;
  80. tt_assert(tor_isinf(INFINITY_DBL));
  81. tt_assert(!tor_isinf(NAN_DBL));
  82. tt_assert(!tor_isinf(DBL_EPSILON));
  83. tt_assert(!tor_isinf(DBL_MAX));
  84. tt_assert(!tor_isinf(DBL_MIN));
  85. tt_assert(!tor_isinf(0.0));
  86. tt_assert(!tor_isinf(0.1));
  87. tt_assert(!tor_isinf(3));
  88. tt_assert(!tor_isinf(3.14));
  89. done:
  90. ;
  91. }
  92. /* XXXX this is a minimal wrapper to make the unit tests compile with the
  93. * changed tor_timegm interface. */
  94. static time_t
  95. tor_timegm_wrapper(const struct tm *tm)
  96. {
  97. time_t t;
  98. if (tor_timegm(tm, &t) < 0)
  99. return -1;
  100. return t;
  101. }
  102. #define tor_timegm tor_timegm_wrapper
  103. static void
  104. test_util_read_until_eof_impl(const char *fname, size_t file_len,
  105. size_t read_limit)
  106. {
  107. char *fifo_name = NULL;
  108. char *test_str = NULL;
  109. char *str = NULL;
  110. size_t sz = 9999999;
  111. int fd = -1;
  112. int r;
  113. fifo_name = tor_strdup(get_fname(fname));
  114. test_str = tor_malloc(file_len);
  115. crypto_rand(test_str, file_len);
  116. r = write_bytes_to_file(fifo_name, test_str, file_len, 1);
  117. tt_int_op(r, OP_EQ, 0);
  118. fd = open(fifo_name, O_RDONLY|O_BINARY);
  119. tt_int_op(fd, OP_GE, 0);
  120. str = read_file_to_str_until_eof(fd, read_limit, &sz);
  121. tt_ptr_op(str, OP_NE, NULL);
  122. if (read_limit < file_len)
  123. tt_int_op(sz, OP_EQ, read_limit);
  124. else
  125. tt_int_op(sz, OP_EQ, file_len);
  126. tt_mem_op(test_str, OP_EQ, str, sz);
  127. tt_int_op(str[sz], OP_EQ, '\0');
  128. done:
  129. unlink(fifo_name);
  130. tor_free(fifo_name);
  131. tor_free(test_str);
  132. tor_free(str);
  133. if (fd >= 0)
  134. close(fd);
  135. }
  136. static void
  137. test_util_read_file_eof_tiny_limit(void *arg)
  138. {
  139. (void)arg;
  140. // purposely set limit shorter than what we wrote to the FIFO to
  141. // test the maximum, and that it puts the NUL in the right spot
  142. test_util_read_until_eof_impl("tor_test_fifo_tiny", 5, 4);
  143. }
  144. static void
  145. test_util_read_file_eof_one_loop_a(void *arg)
  146. {
  147. (void)arg;
  148. test_util_read_until_eof_impl("tor_test_fifo_1ka", 1024, 1023);
  149. }
  150. static void
  151. test_util_read_file_eof_one_loop_b(void *arg)
  152. {
  153. (void)arg;
  154. test_util_read_until_eof_impl("tor_test_fifo_1kb", 1024, 1024);
  155. }
  156. static void
  157. test_util_read_file_eof_two_loops(void *arg)
  158. {
  159. (void)arg;
  160. // write more than 1024 bytes to the FIFO to test two passes through
  161. // the loop in the method; if the re-alloc size is changed this
  162. // should be updated as well.
  163. test_util_read_until_eof_impl("tor_test_fifo_2k", 2048, 10000);
  164. }
  165. static void
  166. test_util_read_file_eof_two_loops_b(void *arg)
  167. {
  168. (void)arg;
  169. test_util_read_until_eof_impl("tor_test_fifo_2kb", 2048, 2048);
  170. }
  171. static void
  172. test_util_read_file_eof_zero_bytes(void *arg)
  173. {
  174. (void)arg;
  175. // zero-byte fifo
  176. test_util_read_until_eof_impl("tor_test_fifo_empty", 0, 10000);
  177. }
  178. /* Test the basic expected behaviour for write_chunks_to_file.
  179. * NOTE: This will need to be updated if we ever change the tempfile location
  180. * or extension */
  181. static void
  182. test_util_write_chunks_to_file(void *arg)
  183. {
  184. char *fname = NULL;
  185. char *tempname = NULL;
  186. char *str = NULL;
  187. int r;
  188. struct stat st;
  189. /* These should be two different sizes to ensure the data is different
  190. * between the data file and the temp file's 'known string' */
  191. int temp_str_len = 1024;
  192. int data_str_len = 512;
  193. char *data_str = tor_malloc(data_str_len);
  194. char *temp_str = tor_malloc(temp_str_len);
  195. smartlist_t *chunks = smartlist_new();
  196. sized_chunk_t c = {data_str, data_str_len/2};
  197. sized_chunk_t c2 = {data_str + data_str_len/2, data_str_len/2};
  198. (void)arg;
  199. crypto_rand(temp_str, temp_str_len);
  200. crypto_rand(data_str, data_str_len);
  201. // Ensure it can write multiple chunks
  202. smartlist_add(chunks, &c);
  203. smartlist_add(chunks, &c2);
  204. /*
  205. * Check if it writes using a tempfile
  206. */
  207. fname = tor_strdup(get_fname("write_chunks_with_tempfile"));
  208. tor_asprintf(&tempname, "%s.tmp", fname);
  209. // write a known string to a file where the tempfile will be
  210. r = write_bytes_to_file(tempname, temp_str, temp_str_len, 1);
  211. tt_int_op(r, OP_EQ, 0);
  212. // call write_chunks_to_file
  213. r = write_chunks_to_file(fname, chunks, 1, 0);
  214. tt_int_op(r, OP_EQ, 0);
  215. // assert the file has been written (expected size)
  216. str = read_file_to_str(fname, RFTS_BIN, &st);
  217. tt_assert(str != NULL);
  218. tt_u64_op((uint64_t)st.st_size, OP_EQ, data_str_len);
  219. tt_mem_op(data_str, OP_EQ, str, data_str_len);
  220. tor_free(str);
  221. // assert that the tempfile is removed (should not leave artifacts)
  222. str = read_file_to_str(tempname, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
  223. tt_assert(str == NULL);
  224. // Remove old testfile for second test
  225. r = unlink(fname);
  226. tt_int_op(r, OP_EQ, 0);
  227. tor_free(fname);
  228. tor_free(tempname);
  229. /*
  230. * Check if it skips using a tempfile with flags
  231. */
  232. fname = tor_strdup(get_fname("write_chunks_with_no_tempfile"));
  233. tor_asprintf(&tempname, "%s.tmp", fname);
  234. // write a known string to a file where the tempfile will be
  235. r = write_bytes_to_file(tempname, temp_str, temp_str_len, 1);
  236. tt_int_op(r, OP_EQ, 0);
  237. // call write_chunks_to_file with no_tempfile = true
  238. r = write_chunks_to_file(fname, chunks, 1, 1);
  239. tt_int_op(r, OP_EQ, 0);
  240. // assert the file has been written (expected size)
  241. str = read_file_to_str(fname, RFTS_BIN, &st);
  242. tt_assert(str != NULL);
  243. tt_u64_op((uint64_t)st.st_size, OP_EQ, data_str_len);
  244. tt_mem_op(data_str, OP_EQ, str, data_str_len);
  245. tor_free(str);
  246. // assert the tempfile still contains the known string
  247. str = read_file_to_str(tempname, RFTS_BIN, &st);
  248. tt_assert(str != NULL);
  249. tt_u64_op((uint64_t)st.st_size, OP_EQ, temp_str_len);
  250. tt_mem_op(temp_str, OP_EQ, str, temp_str_len);
  251. done:
  252. unlink(fname);
  253. unlink(tempname);
  254. smartlist_free(chunks);
  255. tor_free(fname);
  256. tor_free(tempname);
  257. tor_free(str);
  258. tor_free(data_str);
  259. tor_free(temp_str);
  260. }
  261. #define _TFE(a, b, f) tt_int_op((a).f, OP_EQ, (b).f)
  262. /** test the minimum set of struct tm fields needed for a unique epoch value
  263. * this is also the set we use to test tor_timegm */
  264. #define TM_EQUAL(a, b) \
  265. TT_STMT_BEGIN \
  266. _TFE(a, b, tm_year); \
  267. _TFE(a, b, tm_mon ); \
  268. _TFE(a, b, tm_mday); \
  269. _TFE(a, b, tm_hour); \
  270. _TFE(a, b, tm_min ); \
  271. _TFE(a, b, tm_sec ); \
  272. TT_STMT_END
  273. static void
  274. test_util_time(void *arg)
  275. {
  276. struct timeval start, end;
  277. struct tm a_time, b_time;
  278. char timestr[128];
  279. time_t t_res;
  280. int i;
  281. struct timeval tv;
  282. /* Test tv_udiff and tv_mdiff */
  283. (void)arg;
  284. start.tv_sec = 5;
  285. start.tv_usec = 5000;
  286. end.tv_sec = 5;
  287. end.tv_usec = 5000;
  288. tt_int_op(0L,OP_EQ, tv_udiff(&start, &end));
  289. tt_int_op(0L,OP_EQ, tv_mdiff(&start, &end));
  290. tt_int_op(0L,OP_EQ, tv_udiff(&end, &start));
  291. tt_int_op(0L,OP_EQ, tv_mdiff(&end, &start));
  292. end.tv_usec = 7000;
  293. tt_int_op(2000L,OP_EQ, tv_udiff(&start, &end));
  294. tt_int_op(2L,OP_EQ, tv_mdiff(&start, &end));
  295. tt_int_op(-2000L,OP_EQ, tv_udiff(&end, &start));
  296. tt_int_op(-2L,OP_EQ, tv_mdiff(&end, &start));
  297. end.tv_sec = 6;
  298. tt_int_op(1002000L,OP_EQ, tv_udiff(&start, &end));
  299. tt_int_op(1002L,OP_EQ, tv_mdiff(&start, &end));
  300. tt_int_op(-1002000L,OP_EQ, tv_udiff(&end, &start));
  301. tt_int_op(-1002L,OP_EQ, tv_mdiff(&end, &start));
  302. end.tv_usec = 0;
  303. tt_int_op(995000L,OP_EQ, tv_udiff(&start, &end));
  304. tt_int_op(995L,OP_EQ, tv_mdiff(&start, &end));
  305. tt_int_op(-995000L,OP_EQ, tv_udiff(&end, &start));
  306. tt_int_op(-995L,OP_EQ, tv_mdiff(&end, &start));
  307. end.tv_sec = 4;
  308. tt_int_op(-1005000L,OP_EQ, tv_udiff(&start, &end));
  309. tt_int_op(-1005L,OP_EQ, tv_mdiff(&start, &end));
  310. tt_int_op(1005000L,OP_EQ, tv_udiff(&end, &start));
  311. tt_int_op(1005L,OP_EQ, tv_mdiff(&end, &start));
  312. /* Negative tv_sec values, these will break on platforms where tv_sec is
  313. * unsigned */
  314. end.tv_sec = -10;
  315. tt_int_op(-15005000L,OP_EQ, tv_udiff(&start, &end));
  316. tt_int_op(-15005L,OP_EQ, tv_mdiff(&start, &end));
  317. tt_int_op(15005000L,OP_EQ, tv_udiff(&end, &start));
  318. tt_int_op(15005L,OP_EQ, tv_mdiff(&end, &start));
  319. start.tv_sec = -100;
  320. tt_int_op(89995000L,OP_EQ, tv_udiff(&start, &end));
  321. tt_int_op(89995L,OP_EQ, tv_mdiff(&start, &end));
  322. tt_int_op(-89995000L,OP_EQ, tv_udiff(&end, &start));
  323. tt_int_op(-89995L,OP_EQ, tv_mdiff(&end, &start));
  324. /* Test that tv_usec values round away from zero when converted to msec */
  325. start.tv_sec = 0;
  326. start.tv_usec = 0;
  327. end.tv_sec = 10;
  328. end.tv_usec = 499;
  329. tt_int_op(10000499L, OP_EQ, tv_udiff(&start, &end));
  330. tt_int_op(10000L, OP_EQ, tv_mdiff(&start, &end));
  331. tt_int_op(-10000499L, OP_EQ, tv_udiff(&end, &start));
  332. tt_int_op(-10000L, OP_EQ, tv_mdiff(&end, &start));
  333. start.tv_sec = 0;
  334. start.tv_usec = 0;
  335. end.tv_sec = 10;
  336. end.tv_usec = 500;
  337. tt_int_op(10000500L, OP_EQ, tv_udiff(&start, &end));
  338. tt_int_op(10001L, OP_EQ, tv_mdiff(&start, &end));
  339. tt_int_op(-10000500L, OP_EQ, tv_udiff(&end, &start));
  340. tt_int_op(-10000L, OP_EQ, tv_mdiff(&end, &start));
  341. start.tv_sec = 0;
  342. start.tv_usec = 0;
  343. end.tv_sec = 10;
  344. end.tv_usec = 501;
  345. tt_int_op(10000501L, OP_EQ, tv_udiff(&start, &end));
  346. tt_int_op(10001L, OP_EQ, tv_mdiff(&start, &end));
  347. tt_int_op(-10000501L, OP_EQ, tv_udiff(&end, &start));
  348. tt_int_op(-10001L, OP_EQ, tv_mdiff(&end, &start));
  349. /* Overflow conditions */
  350. #ifdef _WIN32
  351. /* Would you believe that tv_sec is a long on windows? Of course you would.*/
  352. #define TV_SEC_MAX LONG_MAX
  353. #define TV_SEC_MIN LONG_MIN
  354. #else
  355. /* Some BSDs have struct timeval.tv_sec 64-bit, but time_t (and long) 32-bit
  356. * Which means TIME_MAX is not actually the maximum value of tv_sec.
  357. * But that's ok for the moment, because the code correctly performs 64-bit
  358. * calculations internally, then catches the overflow. */
  359. #define TV_SEC_MAX TIME_MAX
  360. #define TV_SEC_MIN TIME_MIN
  361. #endif /* defined(_WIN32) */
  362. /* Assume tv_usec is an unsigned integer until proven otherwise */
  363. #define TV_USEC_MAX UINT_MAX
  364. /* Overflows in the result type */
  365. /* All comparisons work */
  366. start.tv_sec = 0;
  367. start.tv_usec = 0;
  368. end.tv_sec = LONG_MAX/1000 - 2;
  369. end.tv_usec = 0;
  370. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  371. tt_int_op(end.tv_sec*1000L, OP_EQ, tv_mdiff(&start, &end));
  372. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  373. tt_int_op(-end.tv_sec*1000L, OP_EQ, tv_mdiff(&end, &start));
  374. start.tv_sec = 0;
  375. start.tv_usec = 0;
  376. end.tv_sec = LONG_MAX/1000000 - 1;
  377. end.tv_usec = 0;
  378. tt_int_op(end.tv_sec*1000000L, OP_EQ, tv_udiff(&start, &end));
  379. tt_int_op(end.tv_sec*1000L, OP_EQ, tv_mdiff(&start, &end));
  380. tt_int_op(-end.tv_sec*1000000L, OP_EQ, tv_udiff(&end, &start));
  381. tt_int_op(-end.tv_sec*1000L, OP_EQ, tv_mdiff(&end, &start));
  382. /* No comparisons work */
  383. start.tv_sec = 0;
  384. start.tv_usec = 0;
  385. end.tv_sec = LONG_MAX/1000 + 1;
  386. end.tv_usec = 0;
  387. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  388. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  389. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  390. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  391. start.tv_sec = 0;
  392. start.tv_usec = 0;
  393. end.tv_sec = LONG_MAX/1000000 + 1;
  394. end.tv_usec = 0;
  395. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  396. tt_int_op(end.tv_sec*1000L, OP_EQ, tv_mdiff(&start, &end));
  397. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  398. tt_int_op(-end.tv_sec*1000L, OP_EQ, tv_mdiff(&end, &start));
  399. start.tv_sec = 0;
  400. start.tv_usec = 0;
  401. end.tv_sec = LONG_MAX/1000;
  402. end.tv_usec = TOR_USEC_PER_SEC;
  403. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  404. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  405. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  406. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  407. start.tv_sec = 0;
  408. start.tv_usec = 0;
  409. end.tv_sec = LONG_MAX/1000000;
  410. end.tv_usec = TOR_USEC_PER_SEC;
  411. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  412. tt_int_op((end.tv_sec + 1)*1000L, OP_EQ, tv_mdiff(&start, &end));
  413. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  414. tt_int_op(-(end.tv_sec + 1)*1000L, OP_EQ, tv_mdiff(&end, &start));
  415. /* Overflows on comparison to zero */
  416. start.tv_sec = 0;
  417. start.tv_usec = 0;
  418. end.tv_sec = TV_SEC_MAX;
  419. end.tv_usec = 0;
  420. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  421. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  422. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  423. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  424. end.tv_sec = TV_SEC_MAX;
  425. end.tv_usec = TOR_USEC_PER_SEC;
  426. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  427. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  428. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  429. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  430. end.tv_sec = 0;
  431. end.tv_usec = TV_USEC_MAX;
  432. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  433. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  434. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  435. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  436. end.tv_sec = TV_SEC_MAX;
  437. end.tv_usec = TV_USEC_MAX;
  438. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  439. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  440. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  441. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  442. end.tv_sec = 0;
  443. end.tv_usec = 0;
  444. start.tv_sec = TV_SEC_MIN;
  445. start.tv_usec = 0;
  446. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  447. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  448. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  449. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  450. start.tv_sec = TV_SEC_MIN;
  451. start.tv_usec = TOR_USEC_PER_SEC;
  452. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  453. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  454. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  455. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  456. start.tv_sec = TV_SEC_MIN;
  457. start.tv_usec = TV_USEC_MAX;
  458. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  459. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  460. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  461. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  462. /* overflows on comparison to maxima / minima */
  463. start.tv_sec = TV_SEC_MIN;
  464. start.tv_usec = 0;
  465. end.tv_sec = TV_SEC_MAX;
  466. end.tv_usec = 0;
  467. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  468. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  469. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  470. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  471. end.tv_sec = TV_SEC_MAX;
  472. end.tv_usec = TOR_USEC_PER_SEC;
  473. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  474. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  475. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  476. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  477. end.tv_sec = TV_SEC_MAX;
  478. end.tv_usec = 0;
  479. start.tv_sec = TV_SEC_MIN;
  480. start.tv_usec = 0;
  481. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  482. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  483. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  484. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  485. start.tv_sec = TV_SEC_MIN;
  486. start.tv_usec = TOR_USEC_PER_SEC;
  487. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  488. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  489. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  490. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  491. /* overflows on comparison to maxima / minima with extra usec */
  492. start.tv_sec = TV_SEC_MIN;
  493. start.tv_usec = TOR_USEC_PER_SEC;
  494. end.tv_sec = TV_SEC_MAX;
  495. end.tv_usec = 0;
  496. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  497. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  498. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  499. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  500. end.tv_sec = TV_SEC_MAX;
  501. end.tv_usec = TOR_USEC_PER_SEC;
  502. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  503. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  504. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  505. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  506. end.tv_sec = TV_SEC_MAX;
  507. end.tv_usec = TOR_USEC_PER_SEC;
  508. start.tv_sec = TV_SEC_MIN;
  509. start.tv_usec = 0;
  510. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  511. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  512. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  513. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  514. start.tv_sec = TV_SEC_MIN;
  515. start.tv_usec = TOR_USEC_PER_SEC;
  516. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&start, &end));
  517. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&start, &end));
  518. tt_int_op(LONG_MAX, OP_EQ, tv_udiff(&end, &start));
  519. tt_int_op(LONG_MAX, OP_EQ, tv_mdiff(&end, &start));
  520. /* Test tor_timegm & tor_gmtime_r */
  521. /* The test values here are confirmed to be correct on a platform
  522. * with a working timegm & gmtime_r. */
  523. /* Start with known-zero a_time and b_time.
  524. * This avoids passing uninitialised values to TM_EQUAL in a_time.
  525. * Zeroing may not be needed for b_time, as long as tor_gmtime_r
  526. * never reads the existing values in the structure.
  527. * But we really don't want intermittently failing tests. */
  528. memset(&a_time, 0, sizeof(struct tm));
  529. memset(&b_time, 0, sizeof(struct tm));
  530. a_time.tm_year = 2003-1900;
  531. a_time.tm_mon = 7;
  532. a_time.tm_mday = 30;
  533. a_time.tm_hour = 6;
  534. a_time.tm_min = 14;
  535. a_time.tm_sec = 55;
  536. t_res = 1062224095UL;
  537. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  538. tor_gmtime_r(&t_res, &b_time);
  539. TM_EQUAL(a_time, b_time);
  540. a_time.tm_year = 2004-1900; /* Try a leap year, after feb. */
  541. t_res = 1093846495UL;
  542. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  543. tor_gmtime_r(&t_res, &b_time);
  544. TM_EQUAL(a_time, b_time);
  545. a_time.tm_mon = 1; /* Try a leap year, in feb. */
  546. a_time.tm_mday = 10;
  547. t_res = 1076393695UL;
  548. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  549. tor_gmtime_r(&t_res, &b_time);
  550. TM_EQUAL(a_time, b_time);
  551. a_time.tm_mon = 0;
  552. t_res = 1073715295UL;
  553. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  554. tor_gmtime_r(&t_res, &b_time);
  555. TM_EQUAL(a_time, b_time);
  556. /* This value is in range with 32 bit and 64 bit time_t */
  557. a_time.tm_year = 2037-1900;
  558. t_res = 2115180895UL;
  559. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  560. tor_gmtime_r(&t_res, &b_time);
  561. TM_EQUAL(a_time, b_time);
  562. /* This value is out of range with 32 bit time_t, but in range for 64 bit
  563. * time_t */
  564. a_time.tm_year = 2039-1900;
  565. #if SIZEOF_TIME_T == 4
  566. setup_full_capture_of_logs(LOG_WARN);
  567. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  568. expect_single_log_msg_containing("Result does not fit in tor_timegm");
  569. teardown_capture_of_logs();
  570. #elif SIZEOF_TIME_T == 8
  571. t_res = 2178252895UL;
  572. tt_int_op(t_res, OP_EQ, tor_timegm(&a_time));
  573. tor_gmtime_r(&t_res, &b_time);
  574. TM_EQUAL(a_time, b_time);
  575. #endif /* SIZEOF_TIME_T == 4 || ... */
  576. /* Test tor_timegm out of range */
  577. /* The below tests will all cause a BUG message, so we capture, suppress,
  578. * and detect. */
  579. #define CAPTURE() do { \
  580. setup_full_capture_of_logs(LOG_WARN); \
  581. } while (0)
  582. #define CHECK_TIMEGM_WARNING(msg) do { \
  583. expect_single_log_msg_containing(msg); \
  584. teardown_capture_of_logs(); \
  585. } while (0)
  586. #define CHECK_POSSIBLE_EINVAL() do { \
  587. if (mock_saved_log_n_entries()) { \
  588. expect_single_log_msg_containing("Invalid argument"); \
  589. } \
  590. teardown_capture_of_logs(); \
  591. } while (0)
  592. #define CHECK_TIMEGM_ARG_OUT_OF_RANGE(msg) \
  593. CHECK_TIMEGM_WARNING("Out-of-range argument to tor_timegm")
  594. /* year */
  595. /* Wrong year < 1970 */
  596. a_time.tm_year = 1969-1900;
  597. CAPTURE();
  598. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  599. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  600. a_time.tm_year = -1-1900;
  601. CAPTURE();
  602. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  603. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  604. #if SIZEOF_INT == 4 || SIZEOF_INT == 8
  605. a_time.tm_year = -1*(1 << 16);
  606. CAPTURE();
  607. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  608. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  609. /* one of the smallest tm_year values my 64 bit system supports:
  610. * t_res = -9223372036854775LL without clamping */
  611. a_time.tm_year = -292275055-1900;
  612. CAPTURE();
  613. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  614. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  615. a_time.tm_year = INT32_MIN;
  616. CAPTURE();
  617. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  618. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  619. #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
  620. #if SIZEOF_INT == 8
  621. a_time.tm_year = -1*(1 << 48);
  622. CAPTURE();
  623. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  624. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  625. /* while unlikely, the system's gmtime(_r) could return
  626. * a "correct" retrospective gregorian negative year value,
  627. * which I'm pretty sure is:
  628. * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
  629. * 730485 is the number of days in two millennia, including leap days */
  630. a_time.tm_year = -292277022657-1900;
  631. CAPTURE();
  632. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  633. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  634. a_time.tm_year = INT64_MIN;
  635. CAPTURE();
  636. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  637. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  638. #endif /* SIZEOF_INT == 8 */
  639. /* Wrong year >= INT32_MAX - 1900 */
  640. #if SIZEOF_INT == 4 || SIZEOF_INT == 8
  641. a_time.tm_year = INT32_MAX-1900;
  642. CAPTURE();
  643. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  644. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  645. a_time.tm_year = INT32_MAX;
  646. CAPTURE();
  647. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  648. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  649. #endif /* SIZEOF_INT == 4 || SIZEOF_INT == 8 */
  650. #if SIZEOF_INT == 8
  651. /* one of the largest tm_year values my 64 bit system supports */
  652. a_time.tm_year = 292278994-1900;
  653. CAPTURE();
  654. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  655. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  656. /* while unlikely, the system's gmtime(_r) could return
  657. * a "correct" proleptic gregorian year value,
  658. * which I'm pretty sure is:
  659. * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
  660. * 730485 is the number of days in two millennia, including leap days */
  661. a_time.tm_year = 292277026596-1900;
  662. CAPTURE();
  663. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  664. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  665. a_time.tm_year = INT64_MAX-1900;
  666. CAPTURE();
  667. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  668. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  669. a_time.tm_year = INT64_MAX;
  670. CAPTURE();
  671. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  672. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  673. #endif /* SIZEOF_INT == 8 */
  674. /* month */
  675. a_time.tm_year = 2007-1900; /* restore valid year */
  676. a_time.tm_mon = 12; /* Wrong month, it's 0-based */
  677. CAPTURE();
  678. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  679. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  680. a_time.tm_mon = -1; /* Wrong month */
  681. CAPTURE();
  682. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  683. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  684. /* day */
  685. a_time.tm_mon = 6; /* Try July */
  686. a_time.tm_mday = 32; /* Wrong day */
  687. CAPTURE();
  688. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  689. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  690. a_time.tm_mon = 5; /* Try June */
  691. a_time.tm_mday = 31; /* Wrong day */
  692. CAPTURE();
  693. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  694. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  695. a_time.tm_year = 2008-1900; /* Try a leap year */
  696. a_time.tm_mon = 1; /* in feb. */
  697. a_time.tm_mday = 30; /* Wrong day */
  698. CAPTURE();
  699. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  700. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  701. a_time.tm_year = 2011-1900; /* Try a non-leap year */
  702. a_time.tm_mon = 1; /* in feb. */
  703. a_time.tm_mday = 29; /* Wrong day */
  704. CAPTURE();
  705. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  706. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  707. a_time.tm_mday = 0; /* Wrong day, it's 1-based (to be different) */
  708. CAPTURE();
  709. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  710. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  711. /* hour */
  712. a_time.tm_mday = 3; /* restore valid month day */
  713. a_time.tm_hour = 24; /* Wrong hour, it's 0-based */
  714. CAPTURE();
  715. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  716. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  717. a_time.tm_hour = -1; /* Wrong hour */
  718. CAPTURE();
  719. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  720. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  721. /* minute */
  722. a_time.tm_hour = 22; /* restore valid hour */
  723. a_time.tm_min = 60; /* Wrong minute, it's 0-based */
  724. CAPTURE();
  725. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  726. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  727. a_time.tm_min = -1; /* Wrong minute */
  728. CAPTURE();
  729. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  730. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  731. /* second */
  732. a_time.tm_min = 37; /* restore valid minute */
  733. a_time.tm_sec = 61; /* Wrong second: 0-based with leap seconds */
  734. CAPTURE();
  735. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  736. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  737. a_time.tm_sec = -1; /* Wrong second */
  738. CAPTURE();
  739. tt_int_op((time_t) -1,OP_EQ, tor_timegm(&a_time));
  740. CHECK_TIMEGM_ARG_OUT_OF_RANGE();
  741. /* Test tor_gmtime_r out of range */
  742. /* time_t < 0 yields a year clamped to 1 or 1970,
  743. * depending on whether the implementation of the system gmtime(_r)
  744. * sets struct tm (1) or not (1970) */
  745. t_res = -1;
  746. CAPTURE();
  747. tor_gmtime_r(&t_res, &b_time);
  748. CHECK_POSSIBLE_EINVAL();
  749. tt_assert(b_time.tm_year == (1970-1900) ||
  750. b_time.tm_year == (1969-1900));
  751. if (sizeof(time_t) == 4 || sizeof(time_t) == 8) {
  752. t_res = -1*(1 << 30);
  753. CAPTURE();
  754. tor_gmtime_r(&t_res, &b_time);
  755. CHECK_POSSIBLE_EINVAL();
  756. tt_assert(b_time.tm_year == (1970-1900) ||
  757. b_time.tm_year == (1935-1900));
  758. t_res = INT32_MIN;
  759. CAPTURE();
  760. tor_gmtime_r(&t_res, &b_time);
  761. CHECK_POSSIBLE_EINVAL();
  762. tt_assert(b_time.tm_year == (1970-1900) ||
  763. b_time.tm_year == (1901-1900));
  764. }
  765. #if SIZEOF_TIME_T == 8
  766. {
  767. /* one of the smallest tm_year values my 64 bit system supports:
  768. * b_time.tm_year == (-292275055LL-1900LL) without clamping */
  769. t_res = -9223372036854775LL;
  770. CAPTURE();
  771. tor_gmtime_r(&t_res, &b_time);
  772. CHECK_POSSIBLE_EINVAL();
  773. tt_assert(b_time.tm_year == (1970-1900) ||
  774. b_time.tm_year == (1-1900));
  775. /* while unlikely, the system's gmtime(_r) could return
  776. * a "correct" retrospective gregorian negative year value,
  777. * which I'm pretty sure is:
  778. * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
  779. * 730485 is the number of days in two millennia, including leap days
  780. * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
  781. t_res = INT64_MIN;
  782. CAPTURE();
  783. tor_gmtime_r(&t_res, &b_time);
  784. if (! (b_time.tm_year == (1970-1900) ||
  785. b_time.tm_year == (1-1900))) {
  786. tt_int_op(b_time.tm_year, OP_EQ, 1970-1900);
  787. }
  788. if (b_time.tm_year != 1970-1900) {
  789. CHECK_TIMEGM_WARNING("Rounding up to ");
  790. } else {
  791. teardown_capture_of_logs();
  792. }
  793. }
  794. {
  795. /* As above, but with localtime. */
  796. t_res = -9223372036854775LL;
  797. CAPTURE();
  798. tor_localtime_r(&t_res, &b_time);
  799. CHECK_POSSIBLE_EINVAL();
  800. tt_assert(b_time.tm_year == (1970-1900) ||
  801. b_time.tm_year == (1-1900));
  802. /* while unlikely, the system's gmtime(_r) could return
  803. * a "correct" retrospective gregorian negative year value,
  804. * which I'm pretty sure is:
  805. * -1*(2^63)/60/60/24*2000/730485 + 1970 = -292277022657
  806. * 730485 is the number of days in two millennia, including leap days
  807. * (int64_t)b_time.tm_year == (-292277022657LL-1900LL) without clamping */
  808. t_res = INT64_MIN;
  809. CAPTURE();
  810. tor_localtime_r(&t_res, &b_time);
  811. if (! (b_time.tm_year == (1970-1900) ||
  812. b_time.tm_year == (1-1900))) {
  813. tt_int_op(b_time.tm_year, OP_EQ, 1970-1900);
  814. }
  815. if (b_time.tm_year != 1970-1900) {
  816. CHECK_TIMEGM_WARNING("Rounding up to ");
  817. } else {
  818. teardown_capture_of_logs();
  819. }
  820. }
  821. #endif /* SIZEOF_TIME_T == 8 */
  822. /* time_t >= INT_MAX yields a year clamped to 2037 or 9999,
  823. * depending on whether the implementation of the system gmtime(_r)
  824. * sets struct tm (9999) or not (2037) */
  825. #if SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8
  826. {
  827. t_res = 3*(1 << 29);
  828. tor_gmtime_r(&t_res, &b_time);
  829. tt_assert(b_time.tm_year == (2021-1900));
  830. t_res = INT32_MAX;
  831. tor_gmtime_r(&t_res, &b_time);
  832. tt_assert(b_time.tm_year == (2037-1900) ||
  833. b_time.tm_year == (2038-1900));
  834. }
  835. {
  836. /* as above but with localtime. */
  837. t_res = 3*(1 << 29);
  838. tor_localtime_r(&t_res, &b_time);
  839. tt_assert(b_time.tm_year == (2021-1900));
  840. t_res = INT32_MAX;
  841. tor_localtime_r(&t_res, &b_time);
  842. tt_assert(b_time.tm_year == (2037-1900) ||
  843. b_time.tm_year == (2038-1900));
  844. }
  845. #endif /* SIZEOF_TIME_T == 4 || SIZEOF_TIME_T == 8 */
  846. #if SIZEOF_TIME_T == 8
  847. {
  848. /* one of the largest tm_year values my 64 bit system supports:
  849. * b_time.tm_year == (292278994L-1900L) without clamping */
  850. t_res = 9223372036854775LL;
  851. CAPTURE();
  852. tor_gmtime_r(&t_res, &b_time);
  853. CHECK_POSSIBLE_EINVAL();
  854. tt_assert(b_time.tm_year == (2037-1900) ||
  855. b_time.tm_year == (9999-1900));
  856. /* while unlikely, the system's gmtime(_r) could return
  857. * a "correct" proleptic gregorian year value,
  858. * which I'm pretty sure is:
  859. * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
  860. * 730485 is the number of days in two millennia, including leap days
  861. * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
  862. t_res = INT64_MAX;
  863. CAPTURE();
  864. tor_gmtime_r(&t_res, &b_time);
  865. CHECK_TIMEGM_WARNING("Rounding down to ");
  866. tt_assert(b_time.tm_year == (2037-1900) ||
  867. b_time.tm_year == (9999-1900));
  868. }
  869. {
  870. /* As above but with localtime. */
  871. t_res = 9223372036854775LL;
  872. CAPTURE();
  873. tor_localtime_r(&t_res, &b_time);
  874. CHECK_POSSIBLE_EINVAL();
  875. tt_assert(b_time.tm_year == (2037-1900) ||
  876. b_time.tm_year == (9999-1900));
  877. /* while unlikely, the system's gmtime(_r) could return
  878. * a "correct" proleptic gregorian year value,
  879. * which I'm pretty sure is:
  880. * (2^63-1)/60/60/24*2000/730485 + 1970 = 292277026596
  881. * 730485 is the number of days in two millennia, including leap days
  882. * (int64_t)b_time.tm_year == (292277026596L-1900L) without clamping */
  883. t_res = INT64_MAX;
  884. CAPTURE();
  885. tor_localtime_r(&t_res, &b_time);
  886. CHECK_TIMEGM_WARNING("Rounding down to ");
  887. tt_assert(b_time.tm_year == (2037-1900) ||
  888. b_time.tm_year == (9999-1900));
  889. }
  890. #endif /* SIZEOF_TIME_T == 8 */
  891. /* Test {format,parse}_rfc1123_time */
  892. format_rfc1123_time(timestr, 0);
  893. tt_str_op("Thu, 01 Jan 1970 00:00:00 GMT",OP_EQ, timestr);
  894. format_rfc1123_time(timestr, (time_t)1091580502UL);
  895. tt_str_op("Wed, 04 Aug 2004 00:48:22 GMT",OP_EQ, timestr);
  896. t_res = 0;
  897. i = parse_rfc1123_time(timestr, &t_res);
  898. tt_int_op(0,OP_EQ, i);
  899. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  900. /* This value is in range with 32 bit and 64 bit time_t */
  901. format_rfc1123_time(timestr, (time_t)2080000000UL);
  902. tt_str_op("Fri, 30 Nov 2035 01:46:40 GMT",OP_EQ, timestr);
  903. t_res = 0;
  904. i = parse_rfc1123_time(timestr, &t_res);
  905. tt_int_op(0,OP_EQ, i);
  906. tt_int_op(t_res,OP_EQ, (time_t)2080000000UL);
  907. /* This value is out of range with 32 bit time_t, but in range for 64 bit
  908. * time_t */
  909. CAPTURE();
  910. format_rfc1123_time(timestr, (time_t)2150000000UL);
  911. CHECK_POSSIBLE_EINVAL();
  912. #if SIZEOF_TIME_T == 4
  913. #if 0
  914. /* Wrapping around will have made it this. */
  915. /* On windows, at least, this is clipped to 1 Jan 1970. ??? */
  916. tt_str_op("Sat, 11 Jan 1902 23:45:04 GMT",OP_EQ, timestr);
  917. #endif
  918. /* Make sure that the right date doesn't parse. */
  919. strlcpy(timestr, "Wed, 17 Feb 2038 06:13:20 GMT", sizeof(timestr));
  920. t_res = 0;
  921. CAPTURE();
  922. i = parse_rfc1123_time(timestr, &t_res);
  923. CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
  924. tt_int_op(-1,OP_EQ, i);
  925. #elif SIZEOF_TIME_T == 8
  926. tt_str_op("Wed, 17 Feb 2038 06:13:20 GMT",OP_EQ, timestr);
  927. t_res = 0;
  928. i = parse_rfc1123_time(timestr, &t_res);
  929. tt_int_op(0,OP_EQ, i);
  930. tt_int_op(t_res,OP_EQ, (time_t)2150000000UL);
  931. #endif /* SIZEOF_TIME_T == 4 || ... */
  932. /* The timezone doesn't matter */
  933. t_res = 0;
  934. tt_int_op(0,OP_EQ,
  935. parse_rfc1123_time("Wed, 04 Aug 2004 00:48:22 ZUL", &t_res));
  936. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  937. tt_int_op(-1,OP_EQ,
  938. parse_rfc1123_time("Wed, zz Aug 2004 99-99x99 GMT", &t_res));
  939. tt_int_op(-1,OP_EQ,
  940. parse_rfc1123_time("Wed, 32 Mar 2011 00:00:00 GMT", &t_res));
  941. tt_int_op(-1,OP_EQ,
  942. parse_rfc1123_time("Wed, 30 Mar 2011 24:00:00 GMT", &t_res));
  943. tt_int_op(-1,OP_EQ,
  944. parse_rfc1123_time("Wed, 30 Mar 2011 23:60:00 GMT", &t_res));
  945. tt_int_op(-1,OP_EQ,
  946. parse_rfc1123_time("Wed, 30 Mar 2011 23:59:62 GMT", &t_res));
  947. tt_int_op(-1,OP_EQ,
  948. parse_rfc1123_time("Wed, 30 Mar 1969 23:59:59 GMT", &t_res));
  949. tt_int_op(-1,OP_EQ,
  950. parse_rfc1123_time("Wed, 30 Ene 2011 23:59:59 GMT", &t_res));
  951. tt_int_op(-1,OP_EQ,
  952. parse_rfc1123_time("Wed, 30 Mar 2011 23:59:59 GM", &t_res));
  953. tt_int_op(-1,OP_EQ,
  954. parse_rfc1123_time("Wed, 30 Mar 1900 23:59:59 GMT", &t_res));
  955. /* Leap year. */
  956. tt_int_op(-1,OP_EQ,
  957. parse_rfc1123_time("Wed, 29 Feb 2011 16:00:00 GMT", &t_res));
  958. tt_int_op(0,OP_EQ,
  959. parse_rfc1123_time("Wed, 29 Feb 2012 16:00:00 GMT", &t_res));
  960. /* Leap second plus one */
  961. tt_int_op(-1,OP_EQ,
  962. parse_rfc1123_time("Wed, 30 Mar 2011 23:59:61 GMT", &t_res));
  963. /* Test parse_iso_time */
  964. t_res = 0;
  965. i = parse_iso_time("", &t_res);
  966. tt_int_op(-1,OP_EQ, i);
  967. t_res = 0;
  968. i = parse_iso_time("2004-08-32 00:48:22", &t_res);
  969. tt_int_op(-1,OP_EQ, i);
  970. t_res = 0;
  971. i = parse_iso_time("1969-08-03 00:48:22", &t_res);
  972. tt_int_op(-1,OP_EQ, i);
  973. t_res = 0;
  974. i = parse_iso_time("2004-08-04 00:48:22", &t_res);
  975. tt_int_op(0,OP_EQ, i);
  976. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  977. t_res = 0;
  978. i = parse_iso_time("2004-8-4 0:48:22", &t_res);
  979. tt_int_op(0,OP_EQ, i);
  980. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  981. /* This value is in range with 32 bit and 64 bit time_t */
  982. t_res = 0;
  983. i = parse_iso_time("2035-11-30 01:46:40", &t_res);
  984. tt_int_op(0,OP_EQ, i);
  985. tt_int_op(t_res,OP_EQ, (time_t)2080000000UL);
  986. /* This value is out of range with 32 bit time_t, but in range for 64 bit
  987. * time_t */
  988. t_res = 0;
  989. #if SIZEOF_TIME_T == 4
  990. CAPTURE();
  991. i = parse_iso_time("2038-02-17 06:13:20", &t_res);
  992. tt_int_op(-1,OP_EQ, i);
  993. CHECK_TIMEGM_WARNING("does not fit in tor_timegm");
  994. #elif SIZEOF_TIME_T == 8
  995. i = parse_iso_time("2038-02-17 06:13:20", &t_res);
  996. tt_int_op(0,OP_EQ, i);
  997. tt_int_op(t_res,OP_EQ, (time_t)2150000000UL);
  998. #endif /* SIZEOF_TIME_T == 4 || ... */
  999. tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-zz 99-99x99", &t_res));
  1000. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-32 00:00:00", &t_res));
  1001. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 24:00:00", &t_res));
  1002. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:60:00", &t_res));
  1003. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59:62", &t_res));
  1004. tt_int_op(-1,OP_EQ, parse_iso_time("1969-03-30 23:59:59", &t_res));
  1005. tt_int_op(-1,OP_EQ, parse_iso_time("2011-00-30 23:59:59", &t_res));
  1006. tt_int_op(-1,OP_EQ, parse_iso_time("2147483647-08-29 14:00:00", &t_res));
  1007. tt_int_op(-1,OP_EQ, parse_iso_time("2011-03-30 23:59", &t_res));
  1008. tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22.100", &t_res));
  1009. tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04 00:48:22XYZ", &t_res));
  1010. /* but... that _is_ acceptable if we aren't being strict. */
  1011. t_res = 0;
  1012. i = parse_iso_time_("2004-08-04 00:48:22XYZ", &t_res, 0, 0);
  1013. tt_int_op(0,OP_EQ, i);
  1014. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  1015. /* try nospace variant. */
  1016. t_res = 0;
  1017. i = parse_iso_time_nospace("2004-08-04T00:48:22", &t_res);
  1018. tt_int_op(0,OP_EQ, i);
  1019. tt_int_op(t_res,OP_EQ, (time_t)1091580502UL);
  1020. tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04T00:48:22", &t_res));
  1021. tt_int_op(-1,OP_EQ, parse_iso_time_nospace("2004-08-04 00:48:22", &t_res));
  1022. tt_int_op(-1,OP_EQ, parse_iso_time("2004-08-04x00:48:22", &t_res));
  1023. tt_int_op(-1,OP_EQ, parse_iso_time_nospace("2004-08-04x00:48:22", &t_res));
  1024. /* Test tor_gettimeofday */
  1025. end.tv_sec = 4;
  1026. end.tv_usec = 999990;
  1027. start.tv_sec = 1;
  1028. start.tv_usec = 500;
  1029. tor_gettimeofday(&start);
  1030. /* now make sure time works. */
  1031. tor_gettimeofday(&end);
  1032. /* We might've timewarped a little. */
  1033. tt_int_op(tv_udiff(&start, &end), OP_GE, -5000);
  1034. /* Test format_iso_time */
  1035. tv.tv_sec = (time_t)1326296338UL;
  1036. tv.tv_usec = 3060;
  1037. format_iso_time(timestr, (time_t)tv.tv_sec);
  1038. tt_str_op("2012-01-11 15:38:58",OP_EQ, timestr);
  1039. /* The output of format_local_iso_time will vary by timezone, and setting
  1040. our timezone for testing purposes would be a nontrivial flaky pain.
  1041. Skip this test for now.
  1042. format_local_iso_time(timestr, tv.tv_sec);
  1043. test_streq("2012-01-11 10:38:58", timestr);
  1044. */
  1045. format_iso_time_nospace(timestr, (time_t)tv.tv_sec);
  1046. tt_str_op("2012-01-11T15:38:58",OP_EQ, timestr);
  1047. tt_int_op(strlen(timestr),OP_EQ, ISO_TIME_LEN);
  1048. format_iso_time_nospace_usec(timestr, &tv);
  1049. tt_str_op("2012-01-11T15:38:58.003060",OP_EQ, timestr);
  1050. tt_int_op(strlen(timestr),OP_EQ, ISO_TIME_USEC_LEN);
  1051. tv.tv_usec = 0;
  1052. /* This value is in range with 32 bit and 64 bit time_t */
  1053. tv.tv_sec = (time_t)2080000000UL;
  1054. format_iso_time(timestr, (time_t)tv.tv_sec);
  1055. tt_str_op("2035-11-30 01:46:40",OP_EQ, timestr);
  1056. /* This value is out of range with 32 bit time_t, but in range for 64 bit
  1057. * time_t */
  1058. tv.tv_sec = (time_t)2150000000UL;
  1059. CAPTURE();
  1060. format_iso_time(timestr, (time_t)tv.tv_sec);
  1061. CHECK_POSSIBLE_EINVAL();
  1062. #if SIZEOF_TIME_T == 4
  1063. /* format_iso_time should indicate failure on overflow, but it doesn't yet.
  1064. * Hopefully #18480 will improve the failure semantics in this case.
  1065. tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
  1066. */
  1067. #elif SIZEOF_TIME_T == 8
  1068. #ifndef _WIN32
  1069. /* This SHOULD work on windows too; see bug #18665 */
  1070. tt_str_op("2038-02-17 06:13:20",OP_EQ, timestr);
  1071. #endif
  1072. #endif /* SIZEOF_TIME_T == 4 || ... */
  1073. #undef CAPTURE
  1074. #undef CHECK_TIMEGM_ARG_OUT_OF_RANGE
  1075. #undef CHECK_POSSIBLE_EINVAL
  1076. done:
  1077. teardown_capture_of_logs();
  1078. }
  1079. static void
  1080. test_util_parse_http_time(void *arg)
  1081. {
  1082. struct tm a_time;
  1083. char b[ISO_TIME_LEN+1];
  1084. (void)arg;
  1085. #define T(s) do { \
  1086. format_iso_time(b, tor_timegm(&a_time)); \
  1087. tt_str_op(b, OP_EQ, (s)); \
  1088. b[0]='\0'; \
  1089. } while (0)
  1090. /* Test parse_http_time */
  1091. tt_int_op(-1,OP_EQ,
  1092. parse_http_time("", &a_time));
  1093. tt_int_op(-1,OP_EQ,
  1094. parse_http_time("Sunday, 32 Aug 2004 00:48:22 GMT", &a_time));
  1095. tt_int_op(-1,OP_EQ,
  1096. parse_http_time("Sunday, 3 Aug 1869 00:48:22 GMT", &a_time));
  1097. tt_int_op(-1,OP_EQ,
  1098. parse_http_time("Sunday, 32-Aug-94 00:48:22 GMT", &a_time));
  1099. tt_int_op(-1,OP_EQ,
  1100. parse_http_time("Sunday, 3-Ago-04 00:48:22", &a_time));
  1101. tt_int_op(-1,OP_EQ,
  1102. parse_http_time("Sunday, August the third", &a_time));
  1103. tt_int_op(-1,OP_EQ,
  1104. parse_http_time("Wednesday,,04 Aug 1994 00:48:22 GMT", &a_time));
  1105. tt_int_op(0,OP_EQ,
  1106. parse_http_time("Wednesday, 04 Aug 1994 00:48:22 GMT", &a_time));
  1107. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1108. T("1994-08-04 00:48:22");
  1109. tt_int_op(0,OP_EQ,
  1110. parse_http_time("Wednesday, 4 Aug 1994 0:48:22 GMT", &a_time));
  1111. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1112. T("1994-08-04 00:48:22");
  1113. tt_int_op(0,OP_EQ,
  1114. parse_http_time("Miercoles, 4 Aug 1994 0:48:22 GMT", &a_time));
  1115. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1116. T("1994-08-04 00:48:22");
  1117. tt_int_op(0,OP_EQ,
  1118. parse_http_time("Wednesday, 04-Aug-94 00:48:22 GMT", &a_time));
  1119. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1120. T("1994-08-04 00:48:22");
  1121. tt_int_op(0,OP_EQ,
  1122. parse_http_time("Wednesday, 4-Aug-94 0:48:22 GMT", &a_time));
  1123. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1124. T("1994-08-04 00:48:22");
  1125. tt_int_op(0,OP_EQ,
  1126. parse_http_time("Miercoles, 4-Aug-94 0:48:22 GMT", &a_time));
  1127. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1128. T("1994-08-04 00:48:22");
  1129. tt_int_op(0,OP_EQ, parse_http_time("Wed Aug 04 00:48:22 1994", &a_time));
  1130. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1131. T("1994-08-04 00:48:22");
  1132. tt_int_op(0,OP_EQ, parse_http_time("Wed Aug 4 0:48:22 1994", &a_time));
  1133. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1134. T("1994-08-04 00:48:22");
  1135. tt_int_op(0,OP_EQ, parse_http_time("Mie Aug 4 0:48:22 1994", &a_time));
  1136. tt_int_op((time_t)775961302UL,OP_EQ, tor_timegm(&a_time));
  1137. T("1994-08-04 00:48:22");
  1138. tt_int_op(0,OP_EQ,parse_http_time("Sun, 1 Jan 2012 00:00:00 GMT", &a_time));
  1139. tt_int_op((time_t)1325376000UL,OP_EQ, tor_timegm(&a_time));
  1140. T("2012-01-01 00:00:00");
  1141. tt_int_op(0,OP_EQ,parse_http_time("Mon, 31 Dec 2012 00:00:00 GMT", &a_time));
  1142. tt_int_op((time_t)1356912000UL,OP_EQ, tor_timegm(&a_time));
  1143. T("2012-12-31 00:00:00");
  1144. /* This value is in range with 32 bit and 64 bit time_t */
  1145. tt_int_op(0,OP_EQ,parse_http_time("Fri, 30 Nov 2035 01:46:40 GMT", &a_time));
  1146. tt_int_op((time_t)2080000000UL,OP_EQ, tor_timegm(&a_time));
  1147. T("2035-11-30 01:46:40");
  1148. /* This value is out of range with 32 bit time_t, but in range for 64 bit
  1149. * time_t */
  1150. #if SIZEOF_TIME_T == 4
  1151. /* parse_http_time should indicate failure on overflow, but it doesn't yet.
  1152. * Hopefully #18480 will improve the failure semantics in this case. */
  1153. setup_full_capture_of_logs(LOG_WARN);
  1154. tt_int_op(0,OP_EQ,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time));
  1155. tt_int_op((time_t)-1,OP_EQ, tor_timegm(&a_time));
  1156. expect_single_log_msg_containing("does not fit in tor_timegm");
  1157. teardown_capture_of_logs();
  1158. #elif SIZEOF_TIME_T == 8
  1159. tt_int_op(0,OP_EQ,parse_http_time("Wed, 17 Feb 2038 06:13:20 GMT", &a_time));
  1160. tt_int_op((time_t)2150000000UL,OP_EQ, tor_timegm(&a_time));
  1161. T("2038-02-17 06:13:20");
  1162. #endif /* SIZEOF_TIME_T == 4 || ... */
  1163. tt_int_op(-1,OP_EQ, parse_http_time("2004-08-zz 99-99x99 GMT", &a_time));
  1164. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-32 00:00:00 GMT", &a_time));
  1165. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 24:00:00 GMT", &a_time));
  1166. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:60:00 GMT", &a_time));
  1167. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:59:62 GMT", &a_time));
  1168. tt_int_op(-1,OP_EQ, parse_http_time("1969-03-30 23:59:59 GMT", &a_time));
  1169. tt_int_op(-1,OP_EQ, parse_http_time("2011-00-30 23:59:59 GMT", &a_time));
  1170. tt_int_op(-1,OP_EQ, parse_http_time("2011-03-30 23:59", &a_time));
  1171. #undef T
  1172. done:
  1173. teardown_capture_of_logs();
  1174. }
  1175. static void
  1176. test_util_config_line(void *arg)
  1177. {
  1178. char buf[1024];
  1179. char *k=NULL, *v=NULL;
  1180. const char *str;
  1181. /* Test parse_config_line_from_str */
  1182. (void)arg;
  1183. strlcpy(buf, "k v\n" " key value with spaces \n" "keykey val\n"
  1184. "k2\n"
  1185. "k3 \n" "\n" " \n" "#comment\n"
  1186. "k4#a\n" "k5#abc\n" "k6 val #with comment\n"
  1187. "kseven \"a quoted 'string\"\n"
  1188. "k8 \"a \\x71uoted\\n\\\"str\\\\ing\\t\\001\\01\\1\\\"\"\n"
  1189. "k9 a line that\\\n spans two lines.\n\n"
  1190. "k10 more than\\\n one contin\\\nuation\n"
  1191. "k11 \\\ncontinuation at the start\n"
  1192. "k12 line with a\\\n#comment\n embedded\n"
  1193. "k13\\\ncontinuation at the very start\n"
  1194. "k14 a line that has a comment and # ends with a slash \\\n"
  1195. "k15 this should be the next new line\n"
  1196. "k16 a line that has a comment and # ends without a slash \n"
  1197. "k17 this should be the next new line\n"
  1198. , sizeof(buf));
  1199. str = buf;
  1200. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1201. tt_str_op(k,OP_EQ, "k");
  1202. tt_str_op(v,OP_EQ, "v");
  1203. tor_free(k); tor_free(v);
  1204. tt_assert(!strcmpstart(str, "key value with"));
  1205. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1206. tt_str_op(k,OP_EQ, "key");
  1207. tt_str_op(v,OP_EQ, "value with spaces");
  1208. tor_free(k); tor_free(v);
  1209. tt_assert(!strcmpstart(str, "keykey"));
  1210. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1211. tt_str_op(k,OP_EQ, "keykey");
  1212. tt_str_op(v,OP_EQ, "val");
  1213. tor_free(k); tor_free(v);
  1214. tt_assert(!strcmpstart(str, "k2\n"));
  1215. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1216. tt_str_op(k,OP_EQ, "k2");
  1217. tt_str_op(v,OP_EQ, "");
  1218. tor_free(k); tor_free(v);
  1219. tt_assert(!strcmpstart(str, "k3 \n"));
  1220. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1221. tt_str_op(k,OP_EQ, "k3");
  1222. tt_str_op(v,OP_EQ, "");
  1223. tor_free(k); tor_free(v);
  1224. tt_assert(!strcmpstart(str, "#comment"));
  1225. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1226. tt_str_op(k,OP_EQ, "k4");
  1227. tt_str_op(v,OP_EQ, "");
  1228. tor_free(k); tor_free(v);
  1229. tt_assert(!strcmpstart(str, "k5#abc"));
  1230. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1231. tt_str_op(k,OP_EQ, "k5");
  1232. tt_str_op(v,OP_EQ, "");
  1233. tor_free(k); tor_free(v);
  1234. tt_assert(!strcmpstart(str, "k6"));
  1235. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1236. tt_str_op(k,OP_EQ, "k6");
  1237. tt_str_op(v,OP_EQ, "val");
  1238. tor_free(k); tor_free(v);
  1239. tt_assert(!strcmpstart(str, "kseven"));
  1240. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1241. tt_str_op(k,OP_EQ, "kseven");
  1242. tt_str_op(v,OP_EQ, "a quoted \'string");
  1243. tor_free(k); tor_free(v);
  1244. tt_assert(!strcmpstart(str, "k8 "));
  1245. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1246. tt_str_op(k,OP_EQ, "k8");
  1247. tt_str_op(v,OP_EQ, "a quoted\n\"str\\ing\t\x01\x01\x01\"");
  1248. tor_free(k); tor_free(v);
  1249. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1250. tt_str_op(k,OP_EQ, "k9");
  1251. tt_str_op(v,OP_EQ, "a line that spans two lines.");
  1252. tor_free(k); tor_free(v);
  1253. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1254. tt_str_op(k,OP_EQ, "k10");
  1255. tt_str_op(v,OP_EQ, "more than one continuation");
  1256. tor_free(k); tor_free(v);
  1257. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1258. tt_str_op(k,OP_EQ, "k11");
  1259. tt_str_op(v,OP_EQ, "continuation at the start");
  1260. tor_free(k); tor_free(v);
  1261. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1262. tt_str_op(k,OP_EQ, "k12");
  1263. tt_str_op(v,OP_EQ, "line with a embedded");
  1264. tor_free(k); tor_free(v);
  1265. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1266. tt_str_op(k,OP_EQ, "k13");
  1267. tt_str_op(v,OP_EQ, "continuation at the very start");
  1268. tor_free(k); tor_free(v);
  1269. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1270. tt_str_op(k,OP_EQ, "k14");
  1271. tt_str_op(v,OP_EQ, "a line that has a comment and" );
  1272. tor_free(k); tor_free(v);
  1273. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1274. tt_str_op(k,OP_EQ, "k15");
  1275. tt_str_op(v,OP_EQ, "this should be the next new line");
  1276. tor_free(k); tor_free(v);
  1277. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1278. tt_str_op(k,OP_EQ, "k16");
  1279. tt_str_op(v,OP_EQ, "a line that has a comment and" );
  1280. tor_free(k); tor_free(v);
  1281. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1282. tt_str_op(k,OP_EQ, "k17");
  1283. tt_str_op(v,OP_EQ, "this should be the next new line");
  1284. tor_free(k); tor_free(v);
  1285. tt_str_op(str,OP_EQ, "");
  1286. done:
  1287. tor_free(k);
  1288. tor_free(v);
  1289. }
  1290. static void
  1291. test_util_config_line_quotes(void *arg)
  1292. {
  1293. char buf1[1024];
  1294. char buf2[128];
  1295. char buf3[128];
  1296. char buf4[128];
  1297. char *k=NULL, *v=NULL;
  1298. const char *str;
  1299. /* Test parse_config_line_from_str */
  1300. (void)arg;
  1301. strlcpy(buf1, "kTrailingSpace \"quoted value\" \n"
  1302. "kTrailingGarbage \"quoted value\"trailing garbage\n"
  1303. , sizeof(buf1));
  1304. strlcpy(buf2, "kTrailingSpaceAndGarbage \"quoted value\" trailing space+g\n"
  1305. , sizeof(buf2));
  1306. strlcpy(buf3, "kMultilineTrailingSpace \"mline\\ \nvalue w/ trailing sp\"\n"
  1307. , sizeof(buf3));
  1308. strlcpy(buf4, "kMultilineNoTrailingBackslash \"naked multiline\nvalue\"\n"
  1309. , sizeof(buf4));
  1310. str = buf1;
  1311. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1312. tt_str_op(k,OP_EQ, "kTrailingSpace");
  1313. tt_str_op(v,OP_EQ, "quoted value");
  1314. tor_free(k); tor_free(v);
  1315. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1316. tt_ptr_op(str,OP_EQ, NULL);
  1317. tor_free(k); tor_free(v);
  1318. str = buf2;
  1319. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1320. tt_ptr_op(str,OP_EQ, NULL);
  1321. tor_free(k); tor_free(v);
  1322. str = buf3;
  1323. const char *err = NULL;
  1324. str = parse_config_line_from_str_verbose(str, &k, &v, &err);
  1325. tt_ptr_op(str,OP_EQ, NULL);
  1326. tor_free(k); tor_free(v);
  1327. tt_str_op(err, OP_EQ, "Invalid escape sequence in quoted string");
  1328. str = buf4;
  1329. err = NULL;
  1330. str = parse_config_line_from_str_verbose(str, &k, &v, &err);
  1331. tt_ptr_op(str,OP_EQ, NULL);
  1332. tor_free(k); tor_free(v);
  1333. tt_str_op(err, OP_EQ, "Invalid escape sequence in quoted string");
  1334. done:
  1335. tor_free(k);
  1336. tor_free(v);
  1337. }
  1338. static void
  1339. test_util_config_line_comment_character(void *arg)
  1340. {
  1341. char buf[1024];
  1342. char *k=NULL, *v=NULL;
  1343. const char *str;
  1344. /* Test parse_config_line_from_str */
  1345. (void)arg;
  1346. strlcpy(buf, "k1 \"# in quotes\"\n"
  1347. "k2 some value # some comment\n"
  1348. "k3 /home/user/myTorNetwork#2\n" /* Testcase for #1323 */
  1349. , sizeof(buf));
  1350. str = buf;
  1351. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1352. tt_str_op(k,OP_EQ, "k1");
  1353. tt_str_op(v,OP_EQ, "# in quotes");
  1354. tor_free(k); tor_free(v);
  1355. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1356. tt_str_op(k,OP_EQ, "k2");
  1357. tt_str_op(v,OP_EQ, "some value");
  1358. tor_free(k); tor_free(v);
  1359. tt_str_op(str,OP_EQ, "k3 /home/user/myTorNetwork#2\n");
  1360. #if 0
  1361. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1362. test_streq(k, "k3");
  1363. test_streq(v, "/home/user/myTorNetwork#2");
  1364. tor_free(k); tor_free(v);
  1365. test_streq(str, "");
  1366. #endif /* 0 */
  1367. done:
  1368. tor_free(k);
  1369. tor_free(v);
  1370. }
  1371. static void
  1372. test_util_config_line_escaped_content(void *arg)
  1373. {
  1374. char buf1[1024];
  1375. char buf2[128];
  1376. char buf3[128];
  1377. char buf4[128];
  1378. char buf5[128];
  1379. char buf6[128];
  1380. char *k=NULL, *v=NULL;
  1381. const char *str;
  1382. /* Test parse_config_line_from_str */
  1383. (void)arg;
  1384. strlcpy(buf1, "HexadecimalLower \"\\x2a\"\n"
  1385. "HexadecimalUpper \"\\x2A\"\n"
  1386. "HexadecimalUpperX \"\\X2A\"\n"
  1387. "Octal \"\\52\"\n"
  1388. "Newline \"\\n\"\n"
  1389. "Tab \"\\t\"\n"
  1390. "CarriageReturn \"\\r\"\n"
  1391. "DoubleQuote \"\\\"\"\n"
  1392. "SimpleQuote \"\\'\"\n"
  1393. "Backslash \"\\\\\"\n"
  1394. "Mix \"This is a \\\"star\\\":\\t\\'\\x2a\\'\\nAnd second line\"\n"
  1395. , sizeof(buf1));
  1396. strlcpy(buf2, "BrokenEscapedContent \"\\a\"\n"
  1397. , sizeof(buf2));
  1398. strlcpy(buf3, "BrokenEscapedContent \"\\x\"\n"
  1399. , sizeof(buf3));
  1400. strlcpy(buf4, "BrokenOctal \"\\8\"\n"
  1401. , sizeof(buf4));
  1402. strlcpy(buf5, "BrokenHex \"\\xg4\"\n"
  1403. , sizeof(buf5));
  1404. strlcpy(buf6, "BrokenEscape \"\\"
  1405. , sizeof(buf6));
  1406. str = buf1;
  1407. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1408. tt_str_op(k,OP_EQ, "HexadecimalLower");
  1409. tt_str_op(v,OP_EQ, "*");
  1410. tor_free(k); tor_free(v);
  1411. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1412. tt_str_op(k,OP_EQ, "HexadecimalUpper");
  1413. tt_str_op(v,OP_EQ, "*");
  1414. tor_free(k); tor_free(v);
  1415. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1416. tt_str_op(k,OP_EQ, "HexadecimalUpperX");
  1417. tt_str_op(v,OP_EQ, "*");
  1418. tor_free(k); tor_free(v);
  1419. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1420. tt_str_op(k,OP_EQ, "Octal");
  1421. tt_str_op(v,OP_EQ, "*");
  1422. tor_free(k); tor_free(v);
  1423. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1424. tt_str_op(k,OP_EQ, "Newline");
  1425. tt_str_op(v,OP_EQ, "\n");
  1426. tor_free(k); tor_free(v);
  1427. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1428. tt_str_op(k,OP_EQ, "Tab");
  1429. tt_str_op(v,OP_EQ, "\t");
  1430. tor_free(k); tor_free(v);
  1431. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1432. tt_str_op(k,OP_EQ, "CarriageReturn");
  1433. tt_str_op(v,OP_EQ, "\r");
  1434. tor_free(k); tor_free(v);
  1435. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1436. tt_str_op(k,OP_EQ, "DoubleQuote");
  1437. tt_str_op(v,OP_EQ, "\"");
  1438. tor_free(k); tor_free(v);
  1439. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1440. tt_str_op(k,OP_EQ, "SimpleQuote");
  1441. tt_str_op(v,OP_EQ, "'");
  1442. tor_free(k); tor_free(v);
  1443. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1444. tt_str_op(k,OP_EQ, "Backslash");
  1445. tt_str_op(v,OP_EQ, "\\");
  1446. tor_free(k); tor_free(v);
  1447. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1448. tt_str_op(k,OP_EQ, "Mix");
  1449. tt_str_op(v,OP_EQ, "This is a \"star\":\t'*'\nAnd second line");
  1450. tor_free(k); tor_free(v);
  1451. tt_str_op(str,OP_EQ, "");
  1452. str = buf2;
  1453. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1454. tt_ptr_op(str,OP_EQ, NULL);
  1455. tor_free(k); tor_free(v);
  1456. str = buf3;
  1457. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1458. tt_ptr_op(str,OP_EQ, NULL);
  1459. tor_free(k); tor_free(v);
  1460. str = buf4;
  1461. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1462. tt_ptr_op(str,OP_EQ, NULL);
  1463. tor_free(k); tor_free(v);
  1464. #if 0
  1465. str = buf5;
  1466. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1467. tt_ptr_op(str, OP_EQ, NULL);
  1468. tor_free(k); tor_free(v);
  1469. #endif /* 0 */
  1470. str = buf6;
  1471. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1472. tt_ptr_op(str,OP_EQ, NULL);
  1473. tor_free(k); tor_free(v);
  1474. /* more things to try. */
  1475. /* Bad hex: */
  1476. strlcpy(buf1, "Foo \"\\x9g\"\n", sizeof(buf1));
  1477. strlcpy(buf2, "Foo \"\\xg0\"\n", sizeof(buf2));
  1478. strlcpy(buf3, "Foo \"\\xf\"\n", sizeof(buf3));
  1479. /* bad escape */
  1480. strlcpy(buf4, "Foo \"\\q\"\n", sizeof(buf4));
  1481. /* missing endquote */
  1482. strlcpy(buf5, "Foo \"hello\n", sizeof(buf5));
  1483. /* extra stuff */
  1484. strlcpy(buf6, "Foo \"hello\" world\n", sizeof(buf6));
  1485. str=buf1;
  1486. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1487. tt_ptr_op(str,OP_EQ, NULL);
  1488. tor_free(k); tor_free(v);
  1489. str=buf2;
  1490. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1491. tt_ptr_op(str,OP_EQ, NULL);
  1492. tor_free(k); tor_free(v);
  1493. str=buf3;
  1494. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1495. tt_ptr_op(str,OP_EQ, NULL);
  1496. tor_free(k); tor_free(v);
  1497. str=buf4;
  1498. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1499. tt_ptr_op(str,OP_EQ, NULL);
  1500. tor_free(k); tor_free(v);
  1501. str=buf5;
  1502. str = parse_config_line_from_str_verbose(str, &k, &v, NULL);
  1503. tt_ptr_op(str,OP_EQ, NULL);
  1504. tor_free(k); tor_free(v);
  1505. str=buf6;
  1506. const char *err = NULL;
  1507. str = parse_config_line_from_str_verbose(str, &k, &v, &err);
  1508. tt_ptr_op(str,OP_EQ, NULL);
  1509. tor_free(k); tor_free(v);
  1510. tt_str_op(err,OP_EQ, "Excess data after quoted string");
  1511. done:
  1512. tor_free(k);
  1513. tor_free(v);
  1514. }
  1515. static void
  1516. test_util_config_line_crlf(void *arg)
  1517. {
  1518. char *k=NULL, *v=NULL;
  1519. const char *err = NULL;
  1520. (void)arg;
  1521. const char *str =
  1522. "Hello world\r\n"
  1523. "Hello \"nice big world\"\r\n";
  1524. str = parse_config_line_from_str_verbose(str, &k, &v, &err);
  1525. tt_assert(str);
  1526. tt_str_op(k,OP_EQ,"Hello");
  1527. tt_str_op(v,OP_EQ,"world");
  1528. tt_ptr_op(err, OP_EQ, NULL);
  1529. tor_free(k); tor_free(v);
  1530. str = parse_config_line_from_str_verbose(str, &k, &v, &err);
  1531. tt_assert(str);
  1532. tt_str_op(k,OP_EQ,"Hello");
  1533. tt_str_op(v,OP_EQ,"nice big world");
  1534. tt_ptr_op(err, OP_EQ, NULL);
  1535. tor_free(k); tor_free(v);
  1536. tt_str_op(str,OP_EQ, "");
  1537. done:
  1538. tor_free(k); tor_free(v);
  1539. }
  1540. #ifndef _WIN32
  1541. static void
  1542. test_util_expand_filename(void *arg)
  1543. {
  1544. char *str;
  1545. (void)arg;
  1546. setenv("HOME", "/home/itv", 1); /* For "internal test value" */
  1547. str = expand_filename("");
  1548. tt_str_op("",OP_EQ, str);
  1549. tor_free(str);
  1550. str = expand_filename("/normal/path");
  1551. tt_str_op("/normal/path",OP_EQ, str);
  1552. tor_free(str);
  1553. str = expand_filename("/normal/trailing/path/");
  1554. tt_str_op("/normal/trailing/path/",OP_EQ, str);
  1555. tor_free(str);
  1556. str = expand_filename("~");
  1557. tt_str_op("/home/itv/",OP_EQ, str);
  1558. tor_free(str);
  1559. str = expand_filename("$HOME/nodice");
  1560. tt_str_op("$HOME/nodice",OP_EQ, str);
  1561. tor_free(str);
  1562. str = expand_filename("~/");
  1563. tt_str_op("/home/itv/",OP_EQ, str);
  1564. tor_free(str);
  1565. str = expand_filename("~/foobarqux");
  1566. tt_str_op("/home/itv/foobarqux",OP_EQ, str);
  1567. tor_free(str);
  1568. str = expand_filename("~/../../etc/passwd");
  1569. tt_str_op("/home/itv/../../etc/passwd",OP_EQ, str);
  1570. tor_free(str);
  1571. str = expand_filename("~/trailing/");
  1572. tt_str_op("/home/itv/trailing/",OP_EQ, str);
  1573. tor_free(str);
  1574. /* Ideally we'd test ~anotheruser, but that's shady to test (we'd
  1575. have to somehow inject/fake the get_user_homedir call) */
  1576. /* $HOME ending in a trailing slash */
  1577. setenv("HOME", "/home/itv/", 1);
  1578. str = expand_filename("~");
  1579. tt_str_op("/home/itv/",OP_EQ, str);
  1580. tor_free(str);
  1581. str = expand_filename("~/");
  1582. tt_str_op("/home/itv/",OP_EQ, str);
  1583. tor_free(str);
  1584. str = expand_filename("~/foo");
  1585. tt_str_op("/home/itv/foo",OP_EQ, str);
  1586. tor_free(str);
  1587. /* Try with empty $HOME */
  1588. setenv("HOME", "", 1);
  1589. str = expand_filename("~");
  1590. tt_str_op("/",OP_EQ, str);
  1591. tor_free(str);
  1592. str = expand_filename("~/");
  1593. tt_str_op("/",OP_EQ, str);
  1594. tor_free(str);
  1595. str = expand_filename("~/foobar");
  1596. tt_str_op("/foobar",OP_EQ, str);
  1597. tor_free(str);
  1598. /* Try with $HOME unset */
  1599. unsetenv("HOME");
  1600. str = expand_filename("~");
  1601. tt_str_op("/",OP_EQ, str);
  1602. tor_free(str);
  1603. str = expand_filename("~/");
  1604. tt_str_op("/",OP_EQ, str);
  1605. tor_free(str);
  1606. str = expand_filename("~/foobar");
  1607. tt_str_op("/foobar",OP_EQ, str);
  1608. tor_free(str);
  1609. done:
  1610. tor_free(str);
  1611. }
  1612. #endif /* !defined(_WIN32) */
  1613. /** Test tor_escape_str_for_pt_args(). */
  1614. static void
  1615. test_util_escape_string_socks(void *arg)
  1616. {
  1617. char *escaped_string = NULL;
  1618. /** Simple backslash escape. */
  1619. (void)arg;
  1620. escaped_string = tor_escape_str_for_pt_args("This is a backslash: \\",";\\");
  1621. tt_assert(escaped_string);
  1622. tt_str_op(escaped_string,OP_EQ, "This is a backslash: \\\\");
  1623. tor_free(escaped_string);
  1624. /** Simple semicolon escape. */
  1625. escaped_string = tor_escape_str_for_pt_args("First rule:Do not use ;",";\\");
  1626. tt_assert(escaped_string);
  1627. tt_str_op(escaped_string,OP_EQ, "First rule:Do not use \\;");
  1628. tor_free(escaped_string);
  1629. /** Empty string. */
  1630. escaped_string = tor_escape_str_for_pt_args("", ";\\");
  1631. tt_assert(escaped_string);
  1632. tt_str_op(escaped_string,OP_EQ, "");
  1633. tor_free(escaped_string);
  1634. /** Escape all characters. */
  1635. escaped_string = tor_escape_str_for_pt_args(";\\;\\", ";\\");
  1636. tt_assert(escaped_string);
  1637. tt_str_op(escaped_string,OP_EQ, "\\;\\\\\\;\\\\");
  1638. tor_free(escaped_string);
  1639. escaped_string = tor_escape_str_for_pt_args(";", ";\\");
  1640. tt_assert(escaped_string);
  1641. tt_str_op(escaped_string,OP_EQ, "\\;");
  1642. tor_free(escaped_string);
  1643. done:
  1644. tor_free(escaped_string);
  1645. }
  1646. static void
  1647. test_util_string_is_key_value(void *ptr)
  1648. {
  1649. (void)ptr;
  1650. tt_assert(string_is_key_value(LOG_WARN, "key=value"));
  1651. tt_assert(string_is_key_value(LOG_WARN, "k=v"));
  1652. tt_assert(string_is_key_value(LOG_WARN, "key="));
  1653. tt_assert(string_is_key_value(LOG_WARN, "x="));
  1654. tt_assert(string_is_key_value(LOG_WARN, "xx="));
  1655. tt_assert(!string_is_key_value(LOG_WARN, "=value"));
  1656. tt_assert(!string_is_key_value(LOG_WARN, "=x"));
  1657. tt_assert(!string_is_key_value(LOG_WARN, "="));
  1658. /* ??? */
  1659. /* tt_assert(!string_is_key_value(LOG_WARN, "===")); */
  1660. done:
  1661. ;
  1662. }
  1663. /** Test basic string functionality. */
  1664. static void
  1665. test_util_strmisc(void *arg)
  1666. {
  1667. char buf[1024];
  1668. char *cp_tmp = NULL;
  1669. /* Test strl operations */
  1670. (void)arg;
  1671. tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 0));
  1672. tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 10));
  1673. tt_str_op(buf,OP_EQ, "Hello");
  1674. tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 6));
  1675. tt_str_op(buf,OP_EQ, "Hello");
  1676. tt_int_op(5,OP_EQ, strlcpy(buf, "Hello", 5));
  1677. tt_str_op(buf,OP_EQ, "Hell");
  1678. strlcpy(buf, "Hello", sizeof(buf));
  1679. tt_int_op(10,OP_EQ, strlcat(buf, "Hello", 5));
  1680. /* Test strstrip() */
  1681. strlcpy(buf, "Testing 1 2 3", sizeof(buf));
  1682. tor_strstrip(buf, ",!");
  1683. tt_str_op(buf,OP_EQ, "Testing 1 2 3");
  1684. strlcpy(buf, "!Testing 1 2 3?", sizeof(buf));
  1685. tor_strstrip(buf, "!? ");
  1686. tt_str_op(buf,OP_EQ, "Testing123");
  1687. strlcpy(buf, "!!!Testing 1 2 3??", sizeof(buf));
  1688. tor_strstrip(buf, "!? ");
  1689. tt_str_op(buf,OP_EQ, "Testing123");
  1690. /* Test snprintf */
  1691. /* Returning -1 when there's not enough room in the output buffer */
  1692. tt_int_op(-1,OP_EQ, tor_snprintf(buf, 0, "Foo"));
  1693. tt_int_op(-1,OP_EQ, tor_snprintf(buf, 2, "Foo"));
  1694. tt_int_op(-1,OP_EQ, tor_snprintf(buf, 3, "Foo"));
  1695. tt_int_op(-1,OP_NE, tor_snprintf(buf, 4, "Foo"));
  1696. /* Always NUL-terminate the output */
  1697. tor_snprintf(buf, 5, "abcdef");
  1698. tt_int_op(0,OP_EQ, buf[4]);
  1699. tor_snprintf(buf, 10, "abcdef");
  1700. tt_int_op(0,OP_EQ, buf[6]);
  1701. /* uint64 */
  1702. tor_snprintf(buf, sizeof(buf), "x!%"PRIu64"!x",
  1703. (UINT64_C(12345678901)));
  1704. tt_str_op("x!12345678901!x",OP_EQ, buf);
  1705. /* Test str{,case}cmpstart */
  1706. tt_assert(strcmpstart("abcdef", "abcdef")==0);
  1707. tt_assert(strcmpstart("abcdef", "abc")==0);
  1708. tt_assert(strcmpstart("abcdef", "abd")<0);
  1709. tt_assert(strcmpstart("abcdef", "abb")>0);
  1710. tt_assert(strcmpstart("ab", "abb")<0);
  1711. tt_assert(strcmpstart("ab", "")==0);
  1712. tt_assert(strcmpstart("ab", "ab ")<0);
  1713. tt_assert(strcasecmpstart("abcdef", "abCdEF")==0);
  1714. tt_assert(strcasecmpstart("abcDeF", "abc")==0);
  1715. tt_assert(strcasecmpstart("abcdef", "Abd")<0);
  1716. tt_assert(strcasecmpstart("Abcdef", "abb")>0);
  1717. tt_assert(strcasecmpstart("ab", "Abb")<0);
  1718. tt_assert(strcasecmpstart("ab", "")==0);
  1719. tt_assert(strcasecmpstart("ab", "ab ")<0);
  1720. /* Test str{,case}cmpend */
  1721. tt_assert(strcmpend("abcdef", "abcdef")==0);
  1722. tt_assert(strcmpend("abcdef", "def")==0);
  1723. tt_assert(strcmpend("abcdef", "deg")<0);
  1724. tt_assert(strcmpend("abcdef", "dee")>0);
  1725. tt_assert(strcmpend("ab", "aab")>0);
  1726. tt_assert(strcasecmpend("AbcDEF", "abcdef")==0);
  1727. tt_assert(strcasecmpend("abcdef", "dEF")==0);
  1728. tt_assert(strcasecmpend("abcdef", "Deg")<0);
  1729. tt_assert(strcasecmpend("abcDef", "dee")>0);
  1730. tt_assert(strcasecmpend("AB", "abb")<0);
  1731. /* Test digest_is_zero */
  1732. memset(buf,0,20);
  1733. buf[20] = 'x';
  1734. tt_assert(tor_digest_is_zero(buf));
  1735. buf[19] = 'x';
  1736. tt_assert(!tor_digest_is_zero(buf));
  1737. /* Test mem_is_zero */
  1738. memset(buf,0,128);
  1739. buf[128] = 'x';
  1740. tt_assert(fast_mem_is_zero(buf, 10));
  1741. tt_assert(fast_mem_is_zero(buf, 20));
  1742. tt_assert(fast_mem_is_zero(buf, 128));
  1743. tt_assert(!fast_mem_is_zero(buf, 129));
  1744. buf[60] = (char)255;
  1745. tt_assert(!fast_mem_is_zero(buf, 128));
  1746. buf[0] = (char)1;
  1747. tt_assert(!fast_mem_is_zero(buf, 10));
  1748. /* Test 'escaped' */
  1749. tt_ptr_op(escaped(NULL), OP_EQ, NULL);
  1750. tt_str_op("\"\"",OP_EQ, escaped(""));
  1751. tt_str_op("\"abcd\"",OP_EQ, escaped("abcd"));
  1752. tt_str_op("\"\\\\ \\n\\r\\t\\\"\\'\"",OP_EQ, escaped("\\ \n\r\t\"'"));
  1753. tt_str_op("\"unnecessary \\'backslashes\\'\"",OP_EQ,
  1754. escaped("unnecessary \'backslashes\'"));
  1755. /* Non-printable characters appear as octal */
  1756. tt_str_op("\"z\\001abc\\277d\"",OP_EQ, escaped("z\001abc\277d"));
  1757. tt_str_op("\"z\\336\\255 ;foo\"",OP_EQ, escaped("z\xde\xad\x20;foo"));
  1758. /* Other cases of esc_for_log{,_len} */
  1759. cp_tmp = esc_for_log(NULL);
  1760. tt_str_op(cp_tmp, OP_EQ, "(null)");
  1761. tor_free(cp_tmp);
  1762. cp_tmp = esc_for_log_len("abcdefg", 3);
  1763. tt_str_op(cp_tmp, OP_EQ, "\"abc\"");
  1764. tor_free(cp_tmp);
  1765. cp_tmp = esc_for_log_len("abcdefg", 100);
  1766. tt_str_op(cp_tmp, OP_EQ, "\"abcdefg\"");
  1767. tor_free(cp_tmp);
  1768. /* Test strndup and memdup */
  1769. {
  1770. const char *s = "abcdefghijklmnopqrstuvwxyz";
  1771. cp_tmp = tor_strndup(s, 30);
  1772. tt_str_op(cp_tmp,OP_EQ, s); /* same string, */
  1773. tt_ptr_op(cp_tmp,OP_NE,s); /* but different pointers. */
  1774. tor_free(cp_tmp);
  1775. cp_tmp = tor_strndup(s, 5);
  1776. tt_str_op(cp_tmp,OP_EQ, "abcde");
  1777. tor_free(cp_tmp);
  1778. s = "a\0b\0c\0d\0e\0";
  1779. cp_tmp = tor_memdup(s,10);
  1780. tt_mem_op(cp_tmp,OP_EQ, s, 10); /* same ram, */
  1781. tt_ptr_op(cp_tmp,OP_NE,s); /* but different pointers. */
  1782. tor_free(cp_tmp);
  1783. }
  1784. /* Test str-foo functions */
  1785. cp_tmp = tor_strdup("abcdef");
  1786. tt_assert(tor_strisnonupper(cp_tmp));
  1787. cp_tmp[3] = 'D';
  1788. tt_assert(!tor_strisnonupper(cp_tmp));
  1789. tor_strupper(cp_tmp);
  1790. tt_str_op(cp_tmp,OP_EQ, "ABCDEF");
  1791. tor_strlower(cp_tmp);
  1792. tt_str_op(cp_tmp,OP_EQ, "abcdef");
  1793. tt_assert(tor_strisnonupper(cp_tmp));
  1794. tt_assert(tor_strisprint(cp_tmp));
  1795. cp_tmp[3] = 3;
  1796. tt_assert(!tor_strisprint(cp_tmp));
  1797. tor_free(cp_tmp);
  1798. /* Test memmem and memstr */
  1799. {
  1800. const char *haystack = "abcde";
  1801. tt_ptr_op(tor_memmem(haystack, 5, "ef", 2), OP_EQ, NULL);
  1802. tt_ptr_op(tor_memmem(haystack, 5, "cd", 2),OP_EQ, haystack + 2);
  1803. tt_ptr_op(tor_memmem(haystack, 5, "cde", 3),OP_EQ, haystack + 2);
  1804. tt_ptr_op(tor_memmem(haystack, 4, "cde", 3), OP_EQ, NULL);
  1805. haystack = "ababcad";
  1806. tt_ptr_op(tor_memmem(haystack, 7, "abc", 3),OP_EQ, haystack + 2);
  1807. tt_ptr_op(tor_memmem(haystack, 7, "ad", 2),OP_EQ, haystack + 5);
  1808. tt_ptr_op(tor_memmem(haystack, 7, "cad", 3),OP_EQ, haystack + 4);
  1809. tt_ptr_op(tor_memmem(haystack, 7, "dadad", 5), OP_EQ, NULL);
  1810. tt_ptr_op(tor_memmem(haystack, 7, "abcdefghij", 10), OP_EQ, NULL);
  1811. /* memstr */
  1812. tt_ptr_op(tor_memstr(haystack, 7, "abc"),OP_EQ, haystack + 2);
  1813. tt_ptr_op(tor_memstr(haystack, 7, "cad"),OP_EQ, haystack + 4);
  1814. tt_ptr_op(tor_memstr(haystack, 6, "cad"), OP_EQ, NULL);
  1815. tt_ptr_op(tor_memstr(haystack, 7, "cadd"), OP_EQ, NULL);
  1816. tt_ptr_op(tor_memstr(haystack, 7, "fe"), OP_EQ, NULL);
  1817. tt_ptr_op(tor_memstr(haystack, 7, "ababcade"), OP_EQ, NULL);
  1818. }
  1819. /* Test hex_str */
  1820. {
  1821. char binary_data[68];
  1822. size_t idx;
  1823. for (idx = 0; idx < sizeof(binary_data); ++idx)
  1824. binary_data[idx] = idx;
  1825. tt_str_op(hex_str(binary_data, 0),OP_EQ, "");
  1826. tt_str_op(hex_str(binary_data, 1),OP_EQ, "00");
  1827. tt_str_op(hex_str(binary_data, 17),OP_EQ,
  1828. "000102030405060708090A0B0C0D0E0F10");
  1829. tt_str_op(hex_str(binary_data, 32),OP_EQ,
  1830. "000102030405060708090A0B0C0D0E0F"
  1831. "101112131415161718191A1B1C1D1E1F");
  1832. tt_str_op(hex_str(binary_data, 34),OP_EQ,
  1833. "000102030405060708090A0B0C0D0E0F"
  1834. "101112131415161718191A1B1C1D1E1F");
  1835. /* Repeat these tests for shorter strings after longer strings
  1836. have been tried, to make sure we're correctly terminating strings */
  1837. tt_str_op(hex_str(binary_data, 1),OP_EQ, "00");
  1838. tt_str_op(hex_str(binary_data, 0),OP_EQ, "");
  1839. }
  1840. /* Test strcmp_opt */
  1841. tt_int_op(strcmp_opt("", "foo"), OP_LT, 0);
  1842. tt_int_op(strcmp_opt("", ""), OP_EQ, 0);
  1843. tt_int_op(strcmp_opt("foo", ""), OP_GT, 0);
  1844. tt_int_op(strcmp_opt(NULL, ""), OP_LT, 0);
  1845. tt_int_op(strcmp_opt(NULL, NULL), OP_EQ, 0);
  1846. tt_int_op(strcmp_opt("", NULL), OP_GT, 0);
  1847. tt_int_op(strcmp_opt(NULL, "foo"), OP_LT, 0);
  1848. tt_int_op(strcmp_opt("foo", NULL), OP_GT, 0);
  1849. done:
  1850. tor_free(cp_tmp);
  1851. }
  1852. static void
  1853. test_util_parse_integer(void *arg)
  1854. {
  1855. (void)arg;
  1856. int i;
  1857. char *cp;
  1858. /* Test parse_long */
  1859. /* Empty/zero input */
  1860. tt_int_op(0L,OP_EQ, tor_parse_long("",10,0,100,&i,NULL));
  1861. tt_int_op(0,OP_EQ, i);
  1862. tt_int_op(0L,OP_EQ, tor_parse_long("0",10,0,100,&i,NULL));
  1863. tt_int_op(1,OP_EQ, i);
  1864. /* Normal cases */
  1865. tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,100,&i,NULL));
  1866. tt_int_op(1,OP_EQ, i);
  1867. tt_int_op(10L,OP_EQ, tor_parse_long("10",10,0,10,&i,NULL));
  1868. tt_int_op(1,OP_EQ, i);
  1869. tt_int_op(10L,OP_EQ, tor_parse_long("10",10,10,100,&i,NULL));
  1870. tt_int_op(1,OP_EQ, i);
  1871. tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,100,&i,NULL));
  1872. tt_int_op(1,OP_EQ, i);
  1873. tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-100,0,&i,NULL));
  1874. tt_int_op(1,OP_EQ, i);
  1875. tt_int_op(-50L,OP_EQ, tor_parse_long("-50",10,-50,0,&i,NULL));
  1876. tt_int_op(1,OP_EQ, i);
  1877. /* Extra garbage */
  1878. tt_int_op(0L,OP_EQ, tor_parse_long("10m",10,0,100,&i,NULL));
  1879. tt_int_op(0,OP_EQ, i);
  1880. tt_int_op(0L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,NULL));
  1881. tt_int_op(0,OP_EQ, i);
  1882. tt_int_op(10L,OP_EQ, tor_parse_long("10m",10,0,100,&i,&cp));
  1883. tt_int_op(1,OP_EQ, i);
  1884. tt_str_op(cp,OP_EQ, "m");
  1885. tt_int_op(-50L,OP_EQ, tor_parse_long("-50 plus garbage",10,-100,100,&i,&cp));
  1886. tt_int_op(1,OP_EQ, i);
  1887. tt_str_op(cp,OP_EQ, " plus garbage");
  1888. /* Illogical min max */
  1889. tt_int_op(0L,OP_EQ, tor_parse_long("10",10,50,4,&i,NULL));
  1890. tt_int_op(0,OP_EQ, i);
  1891. tt_int_op(0L,OP_EQ, tor_parse_long("-50",10,100,-100,&i,NULL));
  1892. tt_int_op(0,OP_EQ, i);
  1893. /* Out of bounds */
  1894. tt_int_op(0L,OP_EQ, tor_parse_long("10",10,50,100,&i,NULL));
  1895. tt_int_op(0,OP_EQ, i);
  1896. tt_int_op(0L,OP_EQ, tor_parse_long("-50",10,0,100,&i,NULL));
  1897. tt_int_op(0,OP_EQ, i);
  1898. /* Base different than 10 */
  1899. tt_int_op(2L,OP_EQ, tor_parse_long("10",2,0,100,NULL,NULL));
  1900. tt_int_op(0L,OP_EQ, tor_parse_long("2",2,0,100,NULL,NULL));
  1901. tt_int_op(68284L,OP_EQ, tor_parse_long("10abc",16,0,70000,NULL,NULL));
  1902. tt_int_op(68284L,OP_EQ, tor_parse_long("10ABC",16,0,70000,NULL,NULL));
  1903. tt_int_op(0L,OP_EQ, tor_parse_long("10",-2,0,100,NULL,NULL));
  1904. tt_int_op(0,OP_EQ, tor_parse_long("10ABC",-1,0,70000,&i,NULL));
  1905. tt_int_op(i,OP_EQ, 0);
  1906. /* Test parse_ulong */
  1907. tt_int_op(0UL,OP_EQ, tor_parse_ulong("",10,0,100,NULL,NULL));
  1908. tt_int_op(0UL,OP_EQ, tor_parse_ulong("0",10,0,100,NULL,NULL));
  1909. tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,100,NULL,NULL));
  1910. tt_int_op(0UL,OP_EQ, tor_parse_ulong("10",10,50,100,NULL,NULL));
  1911. tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,0,10,NULL,NULL));
  1912. tt_int_op(10UL,OP_EQ, tor_parse_ulong("10",10,10,100,NULL,NULL));
  1913. tt_int_op(0UL,OP_EQ, tor_parse_ulong("8",8,0,100,NULL,NULL));
  1914. tt_int_op(50UL,OP_EQ, tor_parse_ulong("50",10,50,100,NULL,NULL));
  1915. tt_int_op(0UL,OP_EQ, tor_parse_ulong("-50",10,0,100,NULL,NULL));
  1916. tt_int_op(0UL,OP_EQ, tor_parse_ulong("50",-1,50,100,&i,NULL));
  1917. tt_int_op(0,OP_EQ, i);
  1918. tt_int_op(0UL,OP_EQ, tor_parse_ulong("-50",10,0,100,&i,NULL));
  1919. tt_int_op(0,OP_EQ, i);
  1920. /* Test parse_uint64 */
  1921. tt_assert(UINT64_C(10) == tor_parse_uint64("10 x",10,0,100, &i, &cp));
  1922. tt_int_op(1,OP_EQ, i);
  1923. tt_str_op(cp,OP_EQ, " x");
  1924. tt_assert(UINT64_C(12345678901) ==
  1925. tor_parse_uint64("12345678901",10,0,UINT64_MAX, &i, &cp));
  1926. tt_int_op(1,OP_EQ, i);
  1927. tt_str_op(cp,OP_EQ, "");
  1928. tt_assert(UINT64_C(0) ==
  1929. tor_parse_uint64("12345678901",10,500,INT32_MAX, &i, &cp));
  1930. tt_int_op(0,OP_EQ, i);
  1931. tt_assert(UINT64_C(0) ==
  1932. tor_parse_uint64("123",-1,0,INT32_MAX, &i, &cp));
  1933. tt_int_op(0,OP_EQ, i);
  1934. {
  1935. /* Test parse_double */
  1936. double d = tor_parse_double("10", 0, (double)UINT64_MAX,&i,NULL);
  1937. tt_int_op(1,OP_EQ, i);
  1938. tt_assert(((uint64_t)d) == 10);
  1939. d = tor_parse_double("0", 0, (double)UINT64_MAX,&i,NULL);
  1940. tt_int_op(1,OP_EQ, i);
  1941. tt_assert(((uint64_t)d) == 0);
  1942. d = tor_parse_double(" ", 0, (double)UINT64_MAX,&i,NULL);
  1943. tt_double_op(fabs(d), OP_LT, 1e-10);
  1944. tt_int_op(0,OP_EQ, i);
  1945. d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,NULL);
  1946. tt_double_op(fabs(d), OP_LT, 1e-10);
  1947. tt_int_op(0,OP_EQ, i);
  1948. d = tor_parse_double(".0a", 0, (double)UINT64_MAX,&i,&cp);
  1949. tt_double_op(fabs(d), OP_LT, 1e-10);
  1950. tt_int_op(1,OP_EQ, i);
  1951. d = tor_parse_double("-.0", 0, (double)UINT64_MAX,&i,NULL);
  1952. tt_int_op(1,OP_EQ, i);
  1953. tt_assert(((uint64_t)d) == 0);
  1954. d = tor_parse_double("-10", -100.0, 100.0,&i,NULL);
  1955. tt_int_op(1,OP_EQ, i);
  1956. tt_double_op(fabs(d - -10.0),OP_LT, 1E-12);
  1957. }
  1958. {
  1959. /* Test tor_parse_* where we overflow/underflow the underlying type. */
  1960. /* This string should overflow 64-bit ints. */
  1961. #define TOOBIG "100000000000000000000000000"
  1962. tt_int_op(0L, OP_EQ,
  1963. tor_parse_long(TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
  1964. tt_int_op(i,OP_EQ, 0);
  1965. tt_int_op(0L,OP_EQ,
  1966. tor_parse_long("-"TOOBIG, 10, LONG_MIN, LONG_MAX, &i, NULL));
  1967. tt_int_op(i,OP_EQ, 0);
  1968. tt_int_op(0UL,OP_EQ, tor_parse_ulong(TOOBIG, 10, 0, ULONG_MAX, &i, NULL));
  1969. tt_int_op(i,OP_EQ, 0);
  1970. tt_u64_op(UINT64_C(0), OP_EQ, tor_parse_uint64(TOOBIG, 10,
  1971. 0, UINT64_MAX, &i, NULL));
  1972. tt_int_op(i,OP_EQ, 0);
  1973. }
  1974. done:
  1975. ;
  1976. }
  1977. static void
  1978. test_util_pow2(void *arg)
  1979. {
  1980. /* Test tor_log2(). */
  1981. (void)arg;
  1982. tt_int_op(tor_log2(64),OP_EQ, 6);
  1983. tt_int_op(tor_log2(65),OP_EQ, 6);
  1984. tt_int_op(tor_log2(63),OP_EQ, 5);
  1985. /* incorrect mathematically, but as specified: */
  1986. tt_int_op(tor_log2(0),OP_EQ, 0);
  1987. tt_int_op(tor_log2(1),OP_EQ, 0);
  1988. tt_int_op(tor_log2(2),OP_EQ, 1);
  1989. tt_int_op(tor_log2(3),OP_EQ, 1);
  1990. tt_int_op(tor_log2(4),OP_EQ, 2);
  1991. tt_int_op(tor_log2(5),OP_EQ, 2);
  1992. tt_int_op(tor_log2(UINT64_C(40000000000000000)),OP_EQ, 55);
  1993. tt_int_op(tor_log2(UINT64_MAX),OP_EQ, 63);
  1994. /* Test round_to_power_of_2 */
  1995. tt_u64_op(round_to_power_of_2(120), OP_EQ, 128);
  1996. tt_u64_op(round_to_power_of_2(128), OP_EQ, 128);
  1997. tt_u64_op(round_to_power_of_2(130), OP_EQ, 128);
  1998. tt_u64_op(round_to_power_of_2(UINT64_C(40000000000000000)), OP_EQ,
  1999. UINT64_C(1)<<55);
  2000. tt_u64_op(round_to_power_of_2(UINT64_C(0xffffffffffffffff)), OP_EQ,
  2001. UINT64_C(1)<<63);
  2002. tt_u64_op(round_to_power_of_2(0), OP_EQ, 1);
  2003. tt_u64_op(round_to_power_of_2(1), OP_EQ, 1);
  2004. tt_u64_op(round_to_power_of_2(2), OP_EQ, 2);
  2005. tt_u64_op(round_to_power_of_2(3), OP_EQ, 2);
  2006. tt_u64_op(round_to_power_of_2(4), OP_EQ, 4);
  2007. tt_u64_op(round_to_power_of_2(5), OP_EQ, 4);
  2008. tt_u64_op(round_to_power_of_2(6), OP_EQ, 4);
  2009. tt_u64_op(round_to_power_of_2(7), OP_EQ, 8);
  2010. done:
  2011. ;
  2012. }
  2013. static void
  2014. test_util_compress_impl(compress_method_t method)
  2015. {
  2016. char *buf1=NULL, *buf2=NULL, *buf3=NULL;
  2017. size_t len1, len2;
  2018. tt_assert(tor_compress_supports_method(method));
  2019. if (method != NO_METHOD) {
  2020. tt_ptr_op(tor_compress_version_str(method), OP_NE, NULL);
  2021. tt_ptr_op(tor_compress_header_version_str(method), OP_NE, NULL);
  2022. }
  2023. buf1 = tor_strdup("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ");
  2024. tt_assert(detect_compression_method(buf1, strlen(buf1)) == UNKNOWN_METHOD);
  2025. tt_assert(!tor_compress(&buf2, &len1, buf1, strlen(buf1)+1, method));
  2026. tt_ptr_op(buf2, OP_NE, NULL);
  2027. if (method == NO_METHOD) {
  2028. // The identity transform doesn't actually compress, and it isn't
  2029. // detectable as "the identity transform."
  2030. tt_int_op(len1, OP_EQ, strlen(buf1)+1);
  2031. tt_int_op(detect_compression_method(buf2, len1), OP_EQ, UNKNOWN_METHOD);
  2032. } else {
  2033. tt_int_op(len1, OP_LT, strlen(buf1));
  2034. tt_int_op(detect_compression_method(buf2, len1), OP_EQ, method);
  2035. }
  2036. tt_assert(!tor_uncompress(&buf3, &len2, buf2, len1, method, 1, LOG_INFO));
  2037. tt_ptr_op(buf3, OP_NE, NULL);
  2038. tt_int_op(strlen(buf1) + 1, OP_EQ, len2);
  2039. tt_str_op(buf1, OP_EQ, buf3);
  2040. tt_int_op(buf3[len2], OP_EQ, 0);
  2041. /* Check whether we can uncompress concatenated, compressed strings. */
  2042. tor_free(buf3);
  2043. buf2 = tor_reallocarray(buf2, len1, 2);
  2044. memcpy(buf2+len1, buf2, len1);
  2045. tt_assert(!tor_uncompress(&buf3, &len2, buf2, len1*2, method, 1, LOG_INFO));
  2046. tt_int_op((strlen(buf1)+1)*2, OP_EQ, len2);
  2047. tt_mem_op(buf3, OP_EQ,
  2048. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0"
  2049. "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZAAAAAAAAAAAAAAAAAAAZ\0",
  2050. (strlen(buf1)+1)*2);
  2051. tt_int_op(buf3[len2], OP_EQ, 0);
  2052. /* Check whether we can uncompress partial strings */
  2053. tor_free(buf1);
  2054. tor_free(buf2);
  2055. tor_free(buf3);
  2056. size_t b1len = 1<<10;
  2057. if (method == ZSTD_METHOD) {
  2058. // zstd needs a big input before it starts generating output that it
  2059. // can partially decompress.
  2060. b1len = 1<<18;
  2061. }
  2062. buf1 = tor_malloc(b1len);
  2063. crypto_rand(buf1, b1len);
  2064. tt_assert(!tor_compress(&buf2, &len1, buf1, b1len, method));
  2065. tt_int_op(len1, OP_GT, 16);
  2066. /* when we allow an incomplete output we should succeed.*/
  2067. tt_assert(!tor_uncompress(&buf3, &len2, buf2, len1-16,
  2068. method, 0, LOG_INFO));
  2069. tt_int_op(len2, OP_GT, 5);
  2070. tt_int_op(len2, OP_LE, len1);
  2071. tt_assert(fast_memeq(buf1, buf3, len2));
  2072. tt_int_op(buf3[len2], OP_EQ, 0);
  2073. /* when we demand a complete output from a real compression method, this
  2074. * must fail. */
  2075. tor_free(buf3);
  2076. if (method != NO_METHOD) {
  2077. tt_assert(tor_uncompress(&buf3, &len2, buf2, len1-16,
  2078. method, 1, LOG_INFO));
  2079. tt_ptr_op(buf3, OP_EQ, NULL);
  2080. }
  2081. done:
  2082. tor_free(buf1);
  2083. tor_free(buf2);
  2084. tor_free(buf3);
  2085. }
  2086. static void
  2087. test_util_compress_stream_impl(compress_method_t method,
  2088. compression_level_t level)
  2089. {
  2090. char *buf1=NULL, *buf2=NULL, *buf3=NULL, *cp1, *cp2;
  2091. const char *ccp2;
  2092. size_t len1, len2;
  2093. tor_compress_state_t *state = NULL;
  2094. state = tor_compress_new(1, method, level);
  2095. tt_assert(state);
  2096. cp1 = buf1 = tor_malloc(1024);
  2097. len1 = 1024;
  2098. ccp2 = "ABCDEFGHIJABCDEFGHIJ";
  2099. len2 = 21;
  2100. tt_int_op(tor_compress_process(state, &cp1, &len1, &ccp2, &len2, 0),
  2101. OP_EQ, TOR_COMPRESS_OK);
  2102. tt_int_op(0, OP_EQ, len2); /* Make sure we compressed it all. */
  2103. tt_assert(cp1 > buf1);
  2104. len2 = 0;
  2105. cp2 = cp1;
  2106. tt_int_op(tor_compress_process(state, &cp1, &len1, &ccp2, &len2, 1),
  2107. OP_EQ, TOR_COMPRESS_DONE);
  2108. tt_int_op(0, OP_EQ, len2);
  2109. if (method == NO_METHOD) {
  2110. tt_ptr_op(cp1, OP_EQ, cp2);
  2111. } else {
  2112. tt_assert(cp1 > cp2); /* Make sure we really added something. */
  2113. }
  2114. tt_int_op(tor_compress_state_size(state), OP_GT, 0);
  2115. tt_assert(!tor_uncompress(&buf3, &len2, buf1, 1024-len1,
  2116. method, 1, LOG_WARN));
  2117. /* Make sure it compressed right. */
  2118. tt_str_op(buf3, OP_EQ, "ABCDEFGHIJABCDEFGHIJ");
  2119. tt_int_op(21, OP_EQ, len2);
  2120. done:
  2121. if (state)
  2122. tor_compress_free(state);
  2123. tor_free(buf1);
  2124. tor_free(buf2);
  2125. tor_free(buf3);
  2126. }
  2127. /** Setup function for compression tests: handles x-zstd:nostatic
  2128. */
  2129. static void *
  2130. compression_test_setup(const struct testcase_t *testcase)
  2131. {
  2132. tor_assert(testcase->setup_data);
  2133. tor_assert(testcase->setup_data != (void*)TT_SKIP);
  2134. const char *methodname = testcase->setup_data;
  2135. if (!strcmp(methodname, "x-zstd:nostatic")) {
  2136. methodname = "x-zstd";
  2137. tor_zstd_set_static_apis_disabled_for_testing(1);
  2138. }
  2139. return (void *)methodname;
  2140. }
  2141. /** Cleanup for compression tests: disables nostatic */
  2142. static int
  2143. compression_test_cleanup(const struct testcase_t *testcase, void *ptr)
  2144. {
  2145. (void)testcase;
  2146. (void)ptr;
  2147. tor_zstd_set_static_apis_disabled_for_testing(0);
  2148. return 1;
  2149. }
  2150. static const struct testcase_setup_t compress_setup = {
  2151. compression_test_setup, compression_test_cleanup
  2152. };
  2153. /** Run unit tests for compression functions */
  2154. static void
  2155. test_util_compress(void *arg)
  2156. {
  2157. const char *methodname = arg;
  2158. tt_assert(methodname);
  2159. compress_method_t method = compression_method_get_by_name(methodname);
  2160. tt_int_op(method, OP_NE, UNKNOWN_METHOD);
  2161. if (! tor_compress_supports_method(method)) {
  2162. tt_skip();
  2163. }
  2164. compression_level_t levels[] = {
  2165. BEST_COMPRESSION,
  2166. HIGH_COMPRESSION,
  2167. MEDIUM_COMPRESSION,
  2168. LOW_COMPRESSION
  2169. };
  2170. test_util_compress_impl(method);
  2171. for (unsigned l = 0; l < ARRAY_LENGTH(levels); ++l) {
  2172. compression_level_t level = levels[l];
  2173. test_util_compress_stream_impl(method, level);
  2174. }
  2175. done:
  2176. ;
  2177. }
  2178. static void
  2179. test_util_decompress_concatenated_impl(compress_method_t method)
  2180. {
  2181. char input[4096];
  2182. char *c1 = NULL, *c2 = NULL, *c3 = NULL;
  2183. char *result = NULL;
  2184. size_t sz1, sz2, sz3, szr;
  2185. int r;
  2186. crypto_rand(input, sizeof(input));
  2187. /* Compress the input in two chunks. */
  2188. r = tor_compress(&c1, &sz1, input, 2048, method);
  2189. tt_int_op(r, OP_EQ, 0);
  2190. r = tor_compress(&c2, &sz2, input+2048, 2048, method);
  2191. tt_int_op(r, OP_EQ, 0);
  2192. /* concatenate the chunks. */
  2193. sz3 = sz1 + sz2;
  2194. c3 = tor_malloc(sz3);
  2195. memcpy(c3, c1, sz1);
  2196. memcpy(c3+sz1, c2, sz2);
  2197. /* decompress the concatenated result */
  2198. r = tor_uncompress(&result, &szr, c3, sz3, method, 0, LOG_WARN);
  2199. tt_int_op(r, OP_EQ, 0);
  2200. tt_int_op(szr, OP_EQ, sizeof(input));
  2201. tt_mem_op(result, OP_EQ, input, sizeof(input));
  2202. done:
  2203. tor_free(c1);
  2204. tor_free(c2);
  2205. tor_free(c3);
  2206. tor_free(result);
  2207. }
  2208. static void
  2209. test_util_decompress_concatenated(void *arg)
  2210. {
  2211. const char *methodname = arg;
  2212. tt_assert(methodname);
  2213. compress_method_t method = compression_method_get_by_name(methodname);
  2214. tt_int_op(method, OP_NE, UNKNOWN_METHOD);
  2215. if (! tor_compress_supports_method(method)) {
  2216. tt_skip();
  2217. }
  2218. test_util_decompress_concatenated_impl(method);
  2219. done:
  2220. ;
  2221. }
  2222. static void
  2223. test_util_decompress_junk_impl(compress_method_t method)
  2224. {
  2225. char input[4096];
  2226. char *result = NULL, *result2 = NULL;
  2227. size_t szr, szr2, sz;
  2228. int r;
  2229. /* This shouldn't be a compressed string according to any method. */
  2230. strlcpy(input, "This shouldn't be a compressed string by any means.",
  2231. sizeof(input));
  2232. sz = strlen(input);
  2233. setup_capture_of_logs(LOG_WARN);
  2234. r = tor_uncompress(&result, &szr, input, sz, method, 0, LOG_WARN);
  2235. tt_int_op(r, OP_EQ, -1);
  2236. tt_ptr_op(result, OP_EQ, NULL);
  2237. expect_log_msg_containing("Error while uncompressing data: bad input?");
  2238. mock_clean_saved_logs();
  2239. /* Now try again, with a compressed object that starts out good and turns to
  2240. junk. */
  2241. crypto_rand(input, sizeof(input));
  2242. r = tor_compress(&result, &szr, input, sizeof(input), method);
  2243. tt_int_op(r, OP_EQ, 0);
  2244. crypto_rand(result+szr/2, szr-(szr/2)); // trash the 2nd half of the result
  2245. r = tor_uncompress(&result2, &szr2, result, szr, method, 0, LOG_WARN);
  2246. tt_int_op(r, OP_EQ, -1);
  2247. expect_log_msg_containing("Error while uncompressing data: bad input?");
  2248. done:
  2249. teardown_capture_of_logs();
  2250. tor_free(result);
  2251. tor_free(result2);
  2252. }
  2253. static void
  2254. test_util_decompress_junk(void *arg)
  2255. {
  2256. const char *methodname = arg;
  2257. tt_assert(methodname);
  2258. compress_method_t method = compression_method_get_by_name(methodname);
  2259. tt_int_op(method, OP_NE, UNKNOWN_METHOD);
  2260. if (! tor_compress_supports_method(method)) {
  2261. tt_skip();
  2262. }
  2263. test_util_decompress_junk_impl(method);
  2264. done:
  2265. ;
  2266. }
  2267. /* mock replacement for tor_compress_is_compression_bomb that doesn't
  2268. * believe in compression bombs. */
  2269. static int
  2270. mock_is_never_compression_bomb(size_t in, size_t out)
  2271. {
  2272. (void)in;
  2273. (void) out;
  2274. return 0;
  2275. }
  2276. static void
  2277. test_util_decompress_dos_impl(compress_method_t method)
  2278. {
  2279. char *input;
  2280. char *result = NULL, *result2 = NULL;
  2281. size_t szr, szr2;
  2282. int r;
  2283. const size_t big = 1024*1024;
  2284. /* one megabyte of 0s. */
  2285. input = tor_malloc_zero(big);
  2286. /* Compress it into "result": it should fail. */
  2287. setup_full_capture_of_logs(LOG_WARN);
  2288. r = tor_compress(&result, &szr, input, big, method);
  2289. tt_int_op(r, OP_EQ, -1);
  2290. expect_log_msg_containing(
  2291. "other Tors would think this was a compression bomb");
  2292. teardown_capture_of_logs();
  2293. /* Try again, but this time suppress compression-bomb detection */
  2294. MOCK(tor_compress_is_compression_bomb, mock_is_never_compression_bomb);
  2295. r = tor_compress(&result, &szr, input, big, method);
  2296. UNMOCK(tor_compress_is_compression_bomb);
  2297. tt_int_op(r, OP_EQ, 0);
  2298. tt_ptr_op(result, OP_NE, NULL);
  2299. /* We should refuse to uncomrpess it again, since it looks like a
  2300. * compression bomb. */
  2301. setup_capture_of_logs(LOG_WARN);
  2302. r = tor_uncompress(&result2, &szr2, result, szr, method, 0, LOG_WARN);
  2303. tt_int_op(r, OP_EQ, -1);
  2304. expect_log_msg_containing("bomb; abandoning stream");
  2305. done:
  2306. teardown_capture_of_logs();
  2307. tor_free(input);
  2308. tor_free(result);
  2309. tor_free(result2);
  2310. }
  2311. static void
  2312. test_util_decompress_dos(void *arg)
  2313. {
  2314. const char *methodname = arg;
  2315. tt_assert(methodname);
  2316. compress_method_t method = compression_method_get_by_name(methodname);
  2317. tt_int_op(method, OP_NE, UNKNOWN_METHOD);
  2318. if (! tor_compress_supports_method(method)) {
  2319. tt_skip();
  2320. }
  2321. test_util_decompress_dos_impl(method);
  2322. done:
  2323. ;
  2324. }
  2325. static void
  2326. test_util_gzip_compression_bomb(void *arg)
  2327. {
  2328. /* A 'compression bomb' is a very small object that uncompresses to a huge
  2329. * one. Most compression formats support them, but they can be a DOS vector.
  2330. * In Tor we try not to generate them, and we don't accept them.
  2331. */
  2332. (void) arg;
  2333. size_t one_million = 1<<20;
  2334. char *one_mb = tor_malloc_zero(one_million);
  2335. char *result = NULL;
  2336. size_t result_len = 0;
  2337. tor_compress_state_t *state = NULL;
  2338. /* Make sure we can't produce a compression bomb */
  2339. setup_full_capture_of_logs(LOG_WARN);
  2340. tt_int_op(-1, OP_EQ, tor_compress(&result, &result_len,
  2341. one_mb, one_million,
  2342. ZLIB_METHOD));
  2343. expect_single_log_msg_containing(
  2344. "We compressed something and got an insanely high "
  2345. "compression factor; other Tors would think this "
  2346. "was a compression bomb.");
  2347. teardown_capture_of_logs();
  2348. /* Here's a compression bomb that we made manually. */
  2349. const char compression_bomb[1039] =
  2350. { 0x78, 0xDA, 0xED, 0xC1, 0x31, 0x01, 0x00, 0x00, 0x00, 0xC2,
  2351. 0xA0, 0xF5, 0x4F, 0x6D, 0x08, 0x5F, 0xA0 /* .... */ };
  2352. tt_int_op(-1, OP_EQ, tor_uncompress(&result, &result_len,
  2353. compression_bomb, 1039,
  2354. ZLIB_METHOD, 0, LOG_WARN));
  2355. /* Now try streaming that. */
  2356. state = tor_compress_new(0, ZLIB_METHOD, HIGH_COMPRESSION);
  2357. tor_compress_output_t r;
  2358. const char *inp = compression_bomb;
  2359. size_t inlen = 1039;
  2360. do {
  2361. char *outp = one_mb;
  2362. size_t outleft = 4096; /* small on purpose */
  2363. r = tor_compress_process(state, &outp, &outleft, &inp, &inlen, 0);
  2364. tt_int_op(inlen, OP_NE, 0);
  2365. } while (r == TOR_COMPRESS_BUFFER_FULL);
  2366. tt_int_op(r, OP_EQ, TOR_COMPRESS_ERROR);
  2367. done:
  2368. tor_free(one_mb);
  2369. tor_compress_free(state);
  2370. }
  2371. /** Run unit tests for mmap() wrapper functionality. */
  2372. static void
  2373. test_util_mmap(void *arg)
  2374. {
  2375. char *fname1 = tor_strdup(get_fname("mapped_1"));
  2376. char *fname2 = tor_strdup(get_fname("mapped_2"));
  2377. char *fname3 = tor_strdup(get_fname("mapped_3"));
  2378. const size_t buflen = 17000;
  2379. char *buf = tor_malloc(17000);
  2380. tor_mmap_t *mapping = NULL;
  2381. (void)arg;
  2382. crypto_rand(buf, buflen);
  2383. mapping = tor_mmap_file(fname1);
  2384. tt_ptr_op(mapping, OP_EQ, NULL);
  2385. write_str_to_file(fname1, "Short file.", 1);
  2386. mapping = tor_mmap_file(fname1);
  2387. tt_assert(mapping);
  2388. tt_int_op(mapping->size,OP_EQ, strlen("Short file."));
  2389. tt_str_op(mapping->data,OP_EQ, "Short file.");
  2390. #ifdef _WIN32
  2391. tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
  2392. mapping = NULL;
  2393. tt_assert(unlink(fname1) == 0);
  2394. #else
  2395. /* make sure we can unlink. */
  2396. tt_assert(unlink(fname1) == 0);
  2397. tt_str_op(mapping->data,OP_EQ, "Short file.");
  2398. tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
  2399. mapping = NULL;
  2400. #endif /* defined(_WIN32) */
  2401. /* Now a zero-length file. */
  2402. write_str_to_file(fname1, "", 1);
  2403. mapping = tor_mmap_file(fname1);
  2404. tt_ptr_op(mapping,OP_EQ, NULL);
  2405. tt_int_op(ERANGE,OP_EQ, errno);
  2406. unlink(fname1);
  2407. /* Make sure that we fail to map a no-longer-existent file. */
  2408. mapping = tor_mmap_file(fname1);
  2409. tt_ptr_op(mapping, OP_EQ, NULL);
  2410. /* Now try a big file that stretches across a few pages and isn't aligned */
  2411. write_bytes_to_file(fname2, buf, buflen, 1);
  2412. mapping = tor_mmap_file(fname2);
  2413. tt_assert(mapping);
  2414. tt_int_op(mapping->size,OP_EQ, buflen);
  2415. tt_mem_op(mapping->data,OP_EQ, buf, buflen);
  2416. tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
  2417. mapping = NULL;
  2418. /* Now try a big aligned file. */
  2419. write_bytes_to_file(fname3, buf, 16384, 1);
  2420. mapping = tor_mmap_file(fname3);
  2421. tt_assert(mapping);
  2422. tt_int_op(mapping->size,OP_EQ, 16384);
  2423. tt_mem_op(mapping->data,OP_EQ, buf, 16384);
  2424. tt_int_op(0, OP_EQ, tor_munmap_file(mapping));
  2425. mapping = NULL;
  2426. done:
  2427. unlink(fname1);
  2428. unlink(fname2);
  2429. unlink(fname3);
  2430. tor_free(fname1);
  2431. tor_free(fname2);
  2432. tor_free(fname3);
  2433. tor_free(buf);
  2434. tor_munmap_file(mapping);
  2435. }
  2436. /** Run unit tests for escaping/unescaping data for use by controllers. */
  2437. static void
  2438. test_util_control_formats(void *arg)
  2439. {
  2440. char *out = NULL;
  2441. const char *inp =
  2442. "..This is a test\r\n.of the emergency \n..system.\r\n\rZ.\r\n";
  2443. size_t sz;
  2444. (void)arg;
  2445. sz = read_escaped_data(inp, strlen(inp), &out);
  2446. tt_str_op(out,OP_EQ,
  2447. ".This is a test\nof the emergency \n.system.\n\rZ.\n");
  2448. tt_int_op(sz,OP_EQ, strlen(out));
  2449. done:
  2450. tor_free(out);
  2451. }
  2452. #define test_feq(value1,value2) do { \
  2453. double v1 = (value1), v2=(value2); \
  2454. double tf_diff = v1-v2; \
  2455. double tf_tolerance = ((v1+v2)/2.0)/1e8; \
  2456. if (tf_diff<0) tf_diff=-tf_diff; \
  2457. if (tf_tolerance<0) tf_tolerance=-tf_tolerance; \
  2458. if (tf_diff<tf_tolerance) { \
  2459. TT_BLATHER(("%s ~~ %s: %f ~~ %f",#value1,#value2,v1,v2)); \
  2460. } else { \
  2461. TT_FAIL(("%s ~~ %s: %f != %f",#value1,#value2,v1,v2)); \
  2462. } \
  2463. } while (0)
  2464. static void
  2465. test_util_sscanf(void *arg)
  2466. {
  2467. unsigned u1, u2, u3;
  2468. unsigned long ulng;
  2469. char s1[20], s2[10], s3[10], ch, *huge = NULL;
  2470. int r;
  2471. long lng1,lng2;
  2472. int int1, int2;
  2473. double d1,d2,d3,d4;
  2474. /* Simple tests (malformed patterns, literal matching, ...) */
  2475. (void)arg;
  2476. tt_int_op(-1,OP_EQ, tor_sscanf("123", "%i", &r)); /* %i is not supported */
  2477. tt_int_op(-1,OP_EQ,
  2478. tor_sscanf("wrong", "%5c", s1)); /* %c cannot have a number. */
  2479. tt_int_op(-1,OP_EQ, tor_sscanf("hello", "%s", s1)); /* %s needs a number. */
  2480. /* this will fail because we don't allow widths longer than 9999 */
  2481. {
  2482. huge = tor_malloc(1000000);
  2483. r = tor_sscanf("prettylongstring", "%99999s", huge);
  2484. tor_free(huge);
  2485. tt_int_op(-1,OP_EQ, r);
  2486. }
  2487. #if 0
  2488. /* GCC thinks these two are illegal. */
  2489. test_eq(-1, tor_sscanf("prettylongstring", "%0s", s1));
  2490. test_eq(0, tor_sscanf("prettylongstring", "%10s", NULL));
  2491. #endif
  2492. /* No '%'-strings: always "success" */
  2493. tt_int_op(0,OP_EQ, tor_sscanf("hello world", "hello world"));
  2494. tt_int_op(0,OP_EQ, tor_sscanf("hello world", "good bye"));
  2495. /* Excess data */
  2496. tt_int_op(0,OP_EQ,
  2497. tor_sscanf("hello 3", "%u", &u1)); /* have to match the start */
  2498. tt_int_op(0,OP_EQ, tor_sscanf(" 3 hello", "%u", &u1));
  2499. tt_int_op(0,OP_EQ,
  2500. tor_sscanf(" 3 hello", "%2u", &u1)); /* not even in this case */
  2501. tt_int_op(1,OP_EQ,
  2502. tor_sscanf("3 hello", "%u", &u1)); /* but trailing is alright */
  2503. /* Numbers (ie. %u) */
  2504. tt_int_op(0,OP_EQ,
  2505. tor_sscanf("hello world 3", "hello worlb %u", &u1)); /* d vs b */
  2506. tt_int_op(1,OP_EQ, tor_sscanf("12345", "%u", &u1));
  2507. tt_int_op(12345u,OP_EQ, u1);
  2508. tt_int_op(1,OP_EQ, tor_sscanf("12346 ", "%u", &u1));
  2509. tt_int_op(12346u,OP_EQ, u1);
  2510. tt_int_op(0,OP_EQ, tor_sscanf(" 12347", "%u", &u1));
  2511. tt_int_op(1,OP_EQ, tor_sscanf(" 12348", " %u", &u1));
  2512. tt_int_op(12348u,OP_EQ, u1);
  2513. tt_int_op(1,OP_EQ, tor_sscanf("0", "%u", &u1));
  2514. tt_int_op(0u,OP_EQ, u1);
  2515. tt_int_op(1,OP_EQ, tor_sscanf("0000", "%u", &u2));
  2516. tt_int_op(0u,OP_EQ, u2);
  2517. tt_int_op(0,OP_EQ, tor_sscanf("", "%u", &u1)); /* absent number */
  2518. tt_int_op(0,OP_EQ, tor_sscanf("A", "%u", &u1)); /* bogus number */
  2519. tt_int_op(0,OP_EQ, tor_sscanf("-1", "%u", &u1)); /* negative number */
  2520. /* Numbers with size (eg. %2u) */
  2521. tt_int_op(0,OP_EQ, tor_sscanf("-1", "%2u", &u1));
  2522. tt_int_op(2,OP_EQ, tor_sscanf("123456", "%2u%u", &u1, &u2));
  2523. tt_int_op(12u,OP_EQ, u1);
  2524. tt_int_op(3456u,OP_EQ, u2);
  2525. tt_int_op(1,OP_EQ, tor_sscanf("123456", "%8u", &u1));
  2526. tt_int_op(123456u,OP_EQ, u1);
  2527. tt_int_op(1,OP_EQ, tor_sscanf("123457 ", "%8u", &u1));
  2528. tt_int_op(123457u,OP_EQ, u1);
  2529. tt_int_op(0,OP_EQ, tor_sscanf(" 123456", "%8u", &u1));
  2530. tt_int_op(3,OP_EQ, tor_sscanf("!12:3:456", "!%2u:%2u:%3u", &u1, &u2, &u3));
  2531. tt_int_op(12u,OP_EQ, u1);
  2532. tt_int_op(3u,OP_EQ, u2);
  2533. tt_int_op(456u,OP_EQ, u3);
  2534. tt_int_op(3,OP_EQ,
  2535. tor_sscanf("67:8:099", "%2u:%2u:%3u", &u1, &u2, &u3)); /* 0s */
  2536. tt_int_op(67u,OP_EQ, u1);
  2537. tt_int_op(8u,OP_EQ, u2);
  2538. tt_int_op(99u,OP_EQ, u3);
  2539. /* %u does not match space.*/
  2540. tt_int_op(2,OP_EQ, tor_sscanf("12:3: 45", "%2u:%2u:%3u", &u1, &u2, &u3));
  2541. tt_int_op(12u,OP_EQ, u1);
  2542. tt_int_op(3u,OP_EQ, u2);
  2543. /* %u does not match negative numbers. */
  2544. tt_int_op(2,OP_EQ, tor_sscanf("67:8:-9", "%2u:%2u:%3u", &u1, &u2, &u3));
  2545. tt_int_op(67u,OP_EQ, u1);
  2546. tt_int_op(8u,OP_EQ, u2);
  2547. /* Arbitrary amounts of 0-padding are okay */
  2548. tt_int_op(3,OP_EQ, tor_sscanf("12:03:000000000000000099", "%2u:%2u:%u",
  2549. &u1, &u2, &u3));
  2550. tt_int_op(12u,OP_EQ, u1);
  2551. tt_int_op(3u,OP_EQ, u2);
  2552. tt_int_op(99u,OP_EQ, u3);
  2553. /* Hex (ie. %x) */
  2554. tt_int_op(3,OP_EQ,
  2555. tor_sscanf("1234 02aBcdEf ff", "%x %x %x", &u1, &u2, &u3));
  2556. tt_int_op(0x1234,OP_EQ, u1);
  2557. tt_int_op(0x2ABCDEF,OP_EQ, u2);
  2558. tt_int_op(0xFF,OP_EQ, u3);
  2559. /* Width works on %x */
  2560. tt_int_op(3,OP_EQ, tor_sscanf("f00dcafe444", "%4x%4x%u", &u1, &u2, &u3));
  2561. tt_int_op(0xf00d,OP_EQ, u1);
  2562. tt_int_op(0xcafe,OP_EQ, u2);
  2563. tt_int_op(444,OP_EQ, u3);
  2564. /* Literal '%' (ie. '%%') */
  2565. tt_int_op(1,OP_EQ, tor_sscanf("99% fresh", "%3u%% fresh", &u1));
  2566. tt_int_op(99,OP_EQ, u1);
  2567. tt_int_op(0,OP_EQ, tor_sscanf("99 fresh", "%% %3u %s", &u1, s1));
  2568. tt_int_op(1,OP_EQ, tor_sscanf("99 fresh", "%3u%% %s", &u1, s1));
  2569. tt_int_op(2,OP_EQ, tor_sscanf("99 fresh", "%3u %5s %%", &u1, s1));
  2570. tt_int_op(99,OP_EQ, u1);
  2571. tt_str_op(s1,OP_EQ, "fresh");
  2572. tt_int_op(1,OP_EQ, tor_sscanf("% boo", "%% %3s", s1));
  2573. tt_str_op("boo",OP_EQ, s1);
  2574. /* Strings (ie. %s) */
  2575. tt_int_op(2,OP_EQ, tor_sscanf("hello", "%3s%7s", s1, s2));
  2576. tt_str_op(s1,OP_EQ, "hel");
  2577. tt_str_op(s2,OP_EQ, "lo");
  2578. tt_int_op(2,OP_EQ, tor_sscanf("WD40", "%2s%u", s3, &u1)); /* %s%u */
  2579. tt_str_op(s3,OP_EQ, "WD");
  2580. tt_int_op(40,OP_EQ, u1);
  2581. tt_int_op(2,OP_EQ, tor_sscanf("WD40", "%3s%u", s3, &u1)); /* %s%u */
  2582. tt_str_op(s3,OP_EQ, "WD4");
  2583. tt_int_op(0,OP_EQ, u1);
  2584. tt_int_op(2,OP_EQ, tor_sscanf("76trombones", "%6u%9s", &u1, s1)); /* %u%s */
  2585. tt_int_op(76,OP_EQ, u1);
  2586. tt_str_op(s1,OP_EQ, "trombones");
  2587. {
  2588. huge = tor_malloc(1000);
  2589. r = tor_sscanf("prettylongstring", "%999s", huge);
  2590. tt_int_op(1,OP_EQ, r);
  2591. tt_str_op(huge,OP_EQ, "prettylongstring");
  2592. tor_free(huge);
  2593. }
  2594. /* %s doesn't eat spaces */
  2595. tt_int_op(2,OP_EQ, tor_sscanf("hello world", "%9s %9s", s1, s2));
  2596. tt_str_op(s1,OP_EQ, "hello");
  2597. tt_str_op(s2,OP_EQ, "world");
  2598. tt_int_op(2,OP_EQ, tor_sscanf("bye world?", "%9s %9s", s1, s2));
  2599. tt_str_op(s1,OP_EQ, "bye");
  2600. tt_str_op(s2,OP_EQ, "");
  2601. tt_int_op(3,OP_EQ,
  2602. tor_sscanf("hi", "%9s%9s%3s", s1, s2, s3)); /* %s can be empty. */
  2603. tt_str_op(s1,OP_EQ, "hi");
  2604. tt_str_op(s2,OP_EQ, "");
  2605. tt_str_op(s3,OP_EQ, "");
  2606. tt_int_op(3,OP_EQ, tor_sscanf("1.2.3", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
  2607. tt_int_op(4,OP_EQ,
  2608. tor_sscanf("1.2.3 foobar", "%u.%u.%u%c", &u1, &u2, &u3, &ch));
  2609. tt_int_op(' ',OP_EQ, ch);
  2610. r = tor_sscanf("12345 -67890 -1", "%d %ld %d", &int1, &lng1, &int2);
  2611. tt_int_op(r,OP_EQ, 3);
  2612. tt_int_op(int1,OP_EQ, 12345);
  2613. tt_int_op(lng1,OP_EQ, -67890);
  2614. tt_int_op(int2,OP_EQ, -1);
  2615. #if SIZEOF_INT == 4
  2616. /* %u */
  2617. /* UINT32_MAX should work */
  2618. tt_int_op(1,OP_EQ, tor_sscanf("4294967295", "%u", &u1));
  2619. tt_int_op(4294967295U,OP_EQ, u1);
  2620. /* But UINT32_MAX + 1 shouldn't work */
  2621. tt_int_op(0,OP_EQ, tor_sscanf("4294967296", "%u", &u1));
  2622. /* but parsing only 9... */
  2623. tt_int_op(1,OP_EQ, tor_sscanf("4294967296", "%9u", &u1));
  2624. tt_int_op(429496729U,OP_EQ, u1);
  2625. /* %x */
  2626. /* UINT32_MAX should work */
  2627. tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFF", "%x", &u1));
  2628. tt_int_op(0xFFFFFFFF,OP_EQ, u1);
  2629. /* But UINT32_MAX + 1 shouldn't work */
  2630. tt_int_op(0,OP_EQ, tor_sscanf("100000000", "%x", &u1));
  2631. /* %d */
  2632. /* INT32_MIN and INT32_MAX should work */
  2633. r = tor_sscanf("-2147483648. 2147483647.", "%d. %d.", &int1, &int2);
  2634. tt_int_op(r,OP_EQ, 2);
  2635. tt_int_op(int1,OP_EQ, -2147483647 - 1);
  2636. tt_int_op(int2,OP_EQ, 2147483647);
  2637. /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
  2638. r = tor_sscanf("-2147483649.", "%d.", &int1);
  2639. tt_int_op(r,OP_EQ, 0);
  2640. r = tor_sscanf("2147483648.", "%d.", &int1);
  2641. tt_int_op(r,OP_EQ, 0);
  2642. /* and the first failure stops further processing */
  2643. r = tor_sscanf("-2147483648. 2147483648.",
  2644. "%d. %d.", &int1, &int2);
  2645. tt_int_op(r,OP_EQ, 1);
  2646. r = tor_sscanf("-2147483649. 2147483647.",
  2647. "%d. %d.", &int1, &int2);
  2648. tt_int_op(r,OP_EQ, 0);
  2649. r = tor_sscanf("2147483648. -2147483649.",
  2650. "%d. %d.", &int1, &int2);
  2651. tt_int_op(r,OP_EQ, 0);
  2652. #elif SIZEOF_INT == 8
  2653. /* %u */
  2654. /* UINT64_MAX should work */
  2655. tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551615", "%u", &u1));
  2656. tt_int_op(18446744073709551615U,OP_EQ, u1);
  2657. /* But UINT64_MAX + 1 shouldn't work */
  2658. tt_int_op(0,OP_EQ, tor_sscanf("18446744073709551616", "%u", &u1));
  2659. /* but parsing only 19... */
  2660. tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551616", "%19u", &u1));
  2661. tt_int_op(1844674407370955161U,OP_EQ, u1);
  2662. /* %x */
  2663. /* UINT64_MAX should work */
  2664. tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFFFFFFFFFF", "%x", &u1));
  2665. tt_int_op(0xFFFFFFFFFFFFFFFF,OP_EQ, u1);
  2666. /* But UINT64_MAX + 1 shouldn't work */
  2667. tt_int_op(0,OP_EQ, tor_sscanf("10000000000000000", "%x", &u1));
  2668. /* %d */
  2669. /* INT64_MIN and INT64_MAX should work */
  2670. r = tor_sscanf("-9223372036854775808. 9223372036854775807.",
  2671. "%d. %d.", &int1, &int2);
  2672. tt_int_op(r,OP_EQ, 2);
  2673. tt_int_op(int1,OP_EQ, -9223372036854775807 - 1);
  2674. tt_int_op(int2,OP_EQ, 9223372036854775807);
  2675. /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
  2676. r = tor_sscanf("-9223372036854775809.", "%d.", &int1);
  2677. tt_int_op(r,OP_EQ, 0);
  2678. r = tor_sscanf("9223372036854775808.", "%d.", &int1);
  2679. tt_int_op(r,OP_EQ, 0);
  2680. /* and the first failure stops further processing */
  2681. r = tor_sscanf("-9223372036854775808. 9223372036854775808.",
  2682. "%d. %d.", &int1, &int2);
  2683. tt_int_op(r,OP_EQ, 1);
  2684. r = tor_sscanf("-9223372036854775809. 9223372036854775807.",
  2685. "%d. %d.", &int1, &int2);
  2686. tt_int_op(r,OP_EQ, 0);
  2687. r = tor_sscanf("9223372036854775808. -9223372036854775809.",
  2688. "%d. %d.", &int1, &int2);
  2689. tt_int_op(r,OP_EQ, 0);
  2690. #endif /* SIZEOF_INT == 4 || ... */
  2691. #if SIZEOF_LONG == 4
  2692. /* %lu */
  2693. /* UINT32_MAX should work */
  2694. tt_int_op(1,OP_EQ, tor_sscanf("4294967295", "%lu", &ulng));
  2695. tt_int_op(4294967295UL,OP_EQ, ulng);
  2696. /* But UINT32_MAX + 1 shouldn't work */
  2697. tt_int_op(0,OP_EQ, tor_sscanf("4294967296", "%lu", &ulng));
  2698. /* but parsing only 9... */
  2699. tt_int_op(1,OP_EQ, tor_sscanf("4294967296", "%9lu", &ulng));
  2700. tt_int_op(429496729UL,OP_EQ, ulng);
  2701. /* %lx */
  2702. /* UINT32_MAX should work */
  2703. tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFF", "%lx", &ulng));
  2704. tt_int_op(0xFFFFFFFFUL,OP_EQ, ulng);
  2705. /* But UINT32_MAX + 1 shouldn't work */
  2706. tt_int_op(0,OP_EQ, tor_sscanf("100000000", "%lx", &ulng));
  2707. /* %ld */
  2708. /* INT32_MIN and INT32_MAX should work */
  2709. r = tor_sscanf("-2147483648. 2147483647.", "%ld. %ld.", &lng1, &lng2);
  2710. tt_int_op(r,OP_EQ, 2);
  2711. tt_int_op(lng1,OP_EQ, -2147483647L - 1L);
  2712. tt_int_op(lng2,OP_EQ, 2147483647L);
  2713. /* But INT32_MIN - 1 and INT32_MAX + 1 shouldn't work */
  2714. r = tor_sscanf("-2147483649.", "%ld.", &lng1);
  2715. tt_int_op(r,OP_EQ, 0);
  2716. r = tor_sscanf("2147483648.", "%ld.", &lng1);
  2717. tt_int_op(r,OP_EQ, 0);
  2718. /* and the first failure stops further processing */
  2719. r = tor_sscanf("-2147483648. 2147483648.",
  2720. "%ld. %ld.", &lng1, &lng2);
  2721. tt_int_op(r,OP_EQ, 1);
  2722. r = tor_sscanf("-2147483649. 2147483647.",
  2723. "%ld. %ld.", &lng1, &lng2);
  2724. tt_int_op(r,OP_EQ, 0);
  2725. r = tor_sscanf("2147483648. -2147483649.",
  2726. "%ld. %ld.", &lng1, &lng2);
  2727. tt_int_op(r,OP_EQ, 0);
  2728. #elif SIZEOF_LONG == 8
  2729. /* %lu */
  2730. /* UINT64_MAX should work */
  2731. tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551615", "%lu", &ulng));
  2732. tt_int_op(18446744073709551615UL,OP_EQ, ulng);
  2733. /* But UINT64_MAX + 1 shouldn't work */
  2734. tt_int_op(0,OP_EQ, tor_sscanf("18446744073709551616", "%lu", &ulng));
  2735. /* but parsing only 19... */
  2736. tt_int_op(1,OP_EQ, tor_sscanf("18446744073709551616", "%19lu", &ulng));
  2737. tt_int_op(1844674407370955161UL,OP_EQ, ulng);
  2738. /* %lx */
  2739. /* UINT64_MAX should work */
  2740. tt_int_op(1,OP_EQ, tor_sscanf("FFFFFFFFFFFFFFFF", "%lx", &ulng));
  2741. tt_int_op(0xFFFFFFFFFFFFFFFFUL,OP_EQ, ulng);
  2742. /* But UINT64_MAX + 1 shouldn't work */
  2743. tt_int_op(0,OP_EQ, tor_sscanf("10000000000000000", "%lx", &ulng));
  2744. /* %ld */
  2745. /* INT64_MIN and INT64_MAX should work */
  2746. r = tor_sscanf("-9223372036854775808. 9223372036854775807.",
  2747. "%ld. %ld.", &lng1, &lng2);
  2748. tt_int_op(r,OP_EQ, 2);
  2749. tt_int_op(lng1,OP_EQ, -9223372036854775807L - 1L);
  2750. tt_int_op(lng2,OP_EQ, 9223372036854775807L);
  2751. /* But INT64_MIN - 1 and INT64_MAX + 1 shouldn't work */
  2752. r = tor_sscanf("-9223372036854775809.", "%ld.", &lng1);
  2753. tt_int_op(r,OP_EQ, 0);
  2754. r = tor_sscanf("9223372036854775808.", "%ld.", &lng1);
  2755. tt_int_op(r,OP_EQ, 0);
  2756. /* and the first failure stops further processing */
  2757. r = tor_sscanf("-9223372036854775808. 9223372036854775808.",
  2758. "%ld. %ld.", &lng1, &lng2);
  2759. tt_int_op(r,OP_EQ, 1);
  2760. r = tor_sscanf("-9223372036854775809. 9223372036854775807.",
  2761. "%ld. %ld.", &lng1, &lng2);
  2762. tt_int_op(r,OP_EQ, 0);
  2763. r = tor_sscanf("9223372036854775808. -9223372036854775809.",
  2764. "%ld. %ld.", &lng1, &lng2);
  2765. tt_int_op(r,OP_EQ, 0);
  2766. #endif /* SIZEOF_LONG == 4 || ... */
  2767. r = tor_sscanf("123.456 .000007 -900123123.2000787 00003.2",
  2768. "%lf %lf %lf %lf", &d1,&d2,&d3,&d4);
  2769. tt_int_op(r,OP_EQ, 4);
  2770. test_feq(d1, 123.456);
  2771. test_feq(d2, .000007);
  2772. test_feq(d3, -900123123.2000787);
  2773. test_feq(d4, 3.2);
  2774. /* missing float */
  2775. r = tor_sscanf("3 ", "%d %lf", &int1, &d1);
  2776. tt_int_op(r, OP_EQ, 1);
  2777. tt_int_op(int1, OP_EQ, 3);
  2778. /* not a float */
  2779. r = tor_sscanf("999 notafloat", "%d %lf", &int1, &d1);
  2780. tt_int_op(r, OP_EQ, 1);
  2781. tt_int_op(int1, OP_EQ, 999);
  2782. /* %s but no buffer. */
  2783. char *nullbuf = NULL;
  2784. r = tor_sscanf("hello", "%3s", nullbuf);
  2785. tt_int_op(r, OP_EQ, 0);
  2786. done:
  2787. tor_free(huge);
  2788. }
  2789. #define tt_char_op(a,op,b) tt_assert_op_type(a,op,b,char,"%c")
  2790. #define tt_ci_char_op(a,op,b) \
  2791. tt_char_op(TOR_TOLOWER((int)a),op,TOR_TOLOWER((int)b))
  2792. #ifndef HAVE_STRNLEN
  2793. static size_t
  2794. strnlen(const char *s, size_t len)
  2795. {
  2796. const char *p = memchr(s, 0, len);
  2797. if (!p)
  2798. return len;
  2799. return p - s;
  2800. }
  2801. #endif /* !defined(HAVE_STRNLEN) */
  2802. static void
  2803. test_util_format_time_interval(void *arg)
  2804. {
  2805. /* use the same sized buffer and integers as tor uses */
  2806. #define DBUF_SIZE 64
  2807. char dbuf[DBUF_SIZE];
  2808. #define T_ "%ld"
  2809. long sec, min, hour, day;
  2810. /* we don't care about the exact spelling of the
  2811. * second(s), minute(s), hour(s), day(s) labels */
  2812. #define LABEL_SIZE 21
  2813. #define L_ "%20s"
  2814. char label_s[LABEL_SIZE];
  2815. char label_m[LABEL_SIZE];
  2816. char label_h[LABEL_SIZE];
  2817. char label_d[LABEL_SIZE];
  2818. #define TL_ T_ " " L_
  2819. int r;
  2820. (void)arg;
  2821. /* In these tests, we're not picky about
  2822. * spelling or abbreviations */
  2823. /* seconds: 0, 1, 9, 10, 59 */
  2824. /* ignore exact spelling of "second(s)"*/
  2825. format_time_interval(dbuf, sizeof(dbuf), 0);
  2826. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2827. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2828. tt_int_op(r,OP_EQ, 2);
  2829. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2830. tt_int_op(sec,OP_EQ, 0);
  2831. format_time_interval(dbuf, sizeof(dbuf), 1);
  2832. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2833. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2834. tt_int_op(r,OP_EQ, 2);
  2835. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2836. tt_int_op(sec,OP_EQ, 1);
  2837. format_time_interval(dbuf, sizeof(dbuf), 10);
  2838. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2839. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2840. tt_int_op(r,OP_EQ, 2);
  2841. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2842. tt_int_op(sec,OP_EQ, 10);
  2843. format_time_interval(dbuf, sizeof(dbuf), 59);
  2844. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2845. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2846. tt_int_op(r,OP_EQ, 2);
  2847. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2848. tt_int_op(sec,OP_EQ, 59);
  2849. /* negative seconds are reported as their absolute value */
  2850. format_time_interval(dbuf, sizeof(dbuf), -4);
  2851. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2852. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2853. tt_int_op(r,OP_EQ, 2);
  2854. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2855. tt_int_op(sec,OP_EQ, 4);
  2856. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2857. format_time_interval(dbuf, sizeof(dbuf), -32);
  2858. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2859. r = tor_sscanf(dbuf, TL_, &sec, label_s);
  2860. tt_int_op(r,OP_EQ, 2);
  2861. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2862. tt_int_op(sec,OP_EQ, 32);
  2863. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2864. /* minutes: 1:00, 1:01, 1:59, 2:00, 2:01, 59:59 */
  2865. /* ignore trailing "0 second(s)", if present */
  2866. format_time_interval(dbuf, sizeof(dbuf), 60);
  2867. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2868. r = tor_sscanf(dbuf, TL_, &min, label_m);
  2869. tt_int_op(r,OP_EQ, 2);
  2870. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2871. tt_int_op(min,OP_EQ, 1);
  2872. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2873. /* ignore exact spelling of "minute(s)," and "second(s)" */
  2874. format_time_interval(dbuf, sizeof(dbuf), 60 + 1);
  2875. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2876. r = tor_sscanf(dbuf, TL_ " " TL_,
  2877. &min, label_m, &sec, label_s);
  2878. tt_int_op(r,OP_EQ, 4);
  2879. tt_int_op(min,OP_EQ, 1);
  2880. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2881. tt_int_op(sec,OP_EQ, 1);
  2882. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2883. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2884. format_time_interval(dbuf, sizeof(dbuf), 60*2 - 1);
  2885. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2886. r = tor_sscanf(dbuf, TL_ " " TL_,
  2887. &min, label_m, &sec, label_s);
  2888. tt_int_op(r,OP_EQ, 4);
  2889. tt_int_op(min,OP_EQ, 1);
  2890. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2891. tt_int_op(sec,OP_EQ, 59);
  2892. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2893. /* ignore trailing "0 second(s)", if present */
  2894. format_time_interval(dbuf, sizeof(dbuf), 60*2);
  2895. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2896. r = tor_sscanf(dbuf, TL_, &min, label_m);
  2897. tt_int_op(r,OP_EQ, 2);
  2898. tt_int_op(min,OP_EQ, 2);
  2899. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2900. /* ignore exact spelling of "minute(s)," and "second(s)" */
  2901. format_time_interval(dbuf, sizeof(dbuf), 60*2 + 1);
  2902. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2903. r = tor_sscanf(dbuf, TL_ " " TL_,
  2904. &min, label_m, &sec, label_s);
  2905. tt_int_op(r,OP_EQ, 4);
  2906. tt_int_op(min,OP_EQ, 2);
  2907. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2908. tt_int_op(sec,OP_EQ, 1);
  2909. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2910. format_time_interval(dbuf, sizeof(dbuf), 60*60 - 1);
  2911. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2912. r = tor_sscanf(dbuf, TL_ " " TL_,
  2913. &min, label_m, &sec, label_s);
  2914. tt_int_op(r,OP_EQ, 4);
  2915. tt_int_op(min,OP_EQ, 59);
  2916. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2917. tt_int_op(sec,OP_EQ, 59);
  2918. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2919. /* negative minutes are reported as their absolute value */
  2920. /* ignore trailing "0 second(s)", if present */
  2921. format_time_interval(dbuf, sizeof(dbuf), -3*60);
  2922. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2923. r = tor_sscanf(dbuf, TL_, &min, label_m);
  2924. tt_int_op(r,OP_EQ, 2);
  2925. tt_int_op(min,OP_EQ, 3);
  2926. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2927. /* ignore exact spelling of "minute(s)," and "second(s)" */
  2928. format_time_interval(dbuf, sizeof(dbuf), -96);
  2929. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2930. r = tor_sscanf(dbuf, TL_ " " TL_,
  2931. &min, label_m, &sec, label_s);
  2932. tt_int_op(r,OP_EQ, 4);
  2933. tt_int_op(min,OP_EQ, 1);
  2934. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2935. tt_int_op(sec,OP_EQ, 36);
  2936. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2937. format_time_interval(dbuf, sizeof(dbuf), -2815);
  2938. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2939. r = tor_sscanf(dbuf, TL_ " " TL_,
  2940. &min, label_m, &sec, label_s);
  2941. tt_int_op(r,OP_EQ, 4);
  2942. tt_int_op(min,OP_EQ, 46);
  2943. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2944. tt_int_op(sec,OP_EQ, 55);
  2945. tt_ci_char_op(label_s[0],OP_EQ, 's');
  2946. /* hours: 1:00, 1:00:01, 1:01, 23:59, 23:59:59 */
  2947. /* always ignore trailing seconds, if present */
  2948. /* ignore trailing "0 minute(s)" etc., if present */
  2949. format_time_interval(dbuf, sizeof(dbuf), 60*60);
  2950. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2951. r = tor_sscanf(dbuf, TL_, &hour, label_h);
  2952. tt_int_op(r,OP_EQ, 2);
  2953. tt_int_op(hour,OP_EQ, 1);
  2954. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2955. format_time_interval(dbuf, sizeof(dbuf), 60*60 + 1);
  2956. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2957. r = tor_sscanf(dbuf, TL_, &hour, label_h);
  2958. tt_int_op(r,OP_EQ, 2);
  2959. tt_int_op(hour,OP_EQ, 1);
  2960. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2961. /* ignore exact spelling of "hour(s)," etc. */
  2962. format_time_interval(dbuf, sizeof(dbuf), 60*60 + 60);
  2963. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2964. r = tor_sscanf(dbuf, TL_ " " TL_,
  2965. &hour, label_h, &min, label_m);
  2966. tt_int_op(r,OP_EQ, 4);
  2967. tt_int_op(hour,OP_EQ, 1);
  2968. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2969. tt_int_op(min,OP_EQ, 1);
  2970. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2971. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 - 60);
  2972. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2973. r = tor_sscanf(dbuf, TL_ " " TL_,
  2974. &hour, label_h, &min, label_m);
  2975. tt_int_op(r,OP_EQ, 4);
  2976. tt_int_op(hour,OP_EQ, 23);
  2977. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2978. tt_int_op(min,OP_EQ, 59);
  2979. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2980. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 - 1);
  2981. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2982. r = tor_sscanf(dbuf, TL_ " " TL_,
  2983. &hour, label_h, &min, label_m);
  2984. tt_int_op(r,OP_EQ, 4);
  2985. tt_int_op(hour,OP_EQ, 23);
  2986. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2987. tt_int_op(min,OP_EQ, 59);
  2988. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  2989. /* negative hours are reported as their absolute value */
  2990. /* ignore exact spelling of "hour(s)," etc., if present */
  2991. format_time_interval(dbuf, sizeof(dbuf), -2*60*60);
  2992. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2993. r = tor_sscanf(dbuf, TL_, &hour, label_h);
  2994. tt_int_op(r,OP_EQ, 2);
  2995. tt_int_op(hour,OP_EQ, 2);
  2996. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  2997. format_time_interval(dbuf, sizeof(dbuf), -75804);
  2998. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  2999. r = tor_sscanf(dbuf, TL_ " " TL_,
  3000. &hour, label_h, &min, label_m);
  3001. tt_int_op(r,OP_EQ, 4);
  3002. tt_int_op(hour,OP_EQ, 21);
  3003. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3004. tt_int_op(min,OP_EQ, 3);
  3005. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3006. /* days: 1:00, 1:00:00:01, 1:00:01, 1:01 */
  3007. /* always ignore trailing seconds, if present */
  3008. /* ignore trailing "0 hours(s)" etc., if present */
  3009. format_time_interval(dbuf, sizeof(dbuf), 24*60*60);
  3010. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3011. r = tor_sscanf(dbuf, TL_, &day, label_d);
  3012. tt_int_op(r,OP_EQ, 2);
  3013. tt_int_op(day,OP_EQ, 1);
  3014. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3015. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 1);
  3016. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3017. r = tor_sscanf(dbuf, TL_, &day, label_d);
  3018. tt_int_op(r,OP_EQ, 2);
  3019. tt_int_op(day,OP_EQ, 1);
  3020. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3021. /* ignore exact spelling of "days(s)," etc. */
  3022. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 60);
  3023. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3024. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  3025. &day, label_d, &hour, label_h, &min, label_m);
  3026. if (r == -1) {
  3027. /* ignore 0 hours(s), if present */
  3028. r = tor_sscanf(dbuf, TL_ " " TL_,
  3029. &day, label_d, &min, label_m);
  3030. }
  3031. tt_assert(r == 4 || r == 6);
  3032. tt_int_op(day,OP_EQ, 1);
  3033. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3034. if (r == 6) {
  3035. tt_int_op(hour,OP_EQ, 0);
  3036. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3037. }
  3038. tt_int_op(min,OP_EQ, 1);
  3039. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3040. /* ignore trailing "0 minutes(s)" etc., if present */
  3041. format_time_interval(dbuf, sizeof(dbuf), 24*60*60 + 60*60);
  3042. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3043. r = tor_sscanf(dbuf, TL_ " " TL_,
  3044. &day, label_d, &hour, label_h);
  3045. tt_int_op(r,OP_EQ, 4);
  3046. tt_int_op(day,OP_EQ, 1);
  3047. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3048. tt_int_op(hour,OP_EQ, 1);
  3049. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3050. /* negative days are reported as their absolute value */
  3051. format_time_interval(dbuf, sizeof(dbuf), -21936184);
  3052. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3053. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  3054. &day, label_d, &hour, label_h, &min, label_m);
  3055. tt_int_op(r,OP_EQ, 6);
  3056. tt_int_op(day,OP_EQ, 253);
  3057. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3058. tt_int_op(hour,OP_EQ, 21);
  3059. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3060. tt_int_op(min,OP_EQ, 23);
  3061. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3062. /* periods > 1 year are reported in days (warn?) */
  3063. /* ignore exact spelling of "days(s)," etc., if present */
  3064. format_time_interval(dbuf, sizeof(dbuf), 758635154);
  3065. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3066. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  3067. &day, label_d, &hour, label_h, &min, label_m);
  3068. tt_int_op(r,OP_EQ, 6);
  3069. tt_int_op(day,OP_EQ, 8780);
  3070. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3071. tt_int_op(hour,OP_EQ, 11);
  3072. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3073. tt_int_op(min,OP_EQ, 59);
  3074. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3075. /* negative periods > 1 year are reported in days (warn?) */
  3076. format_time_interval(dbuf, sizeof(dbuf), -1427014922);
  3077. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3078. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  3079. &day, label_d, &hour, label_h, &min, label_m);
  3080. tt_int_op(r,OP_EQ, 6);
  3081. tt_int_op(day,OP_EQ, 16516);
  3082. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3083. tt_int_op(hour,OP_EQ, 9);
  3084. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3085. tt_int_op(min,OP_EQ, 2);
  3086. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3087. #if SIZEOF_LONG == 4 || SIZEOF_LONG == 8
  3088. /* We can try INT32_MIN/MAX */
  3089. /* Always ignore second(s) */
  3090. /* INT32_MAX */
  3091. format_time_interval(dbuf, sizeof(dbuf), 2147483647);
  3092. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3093. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  3094. &day, label_d, &hour, label_h, &min, label_m);
  3095. tt_int_op(r,OP_EQ, 6);
  3096. tt_int_op(day,OP_EQ, 24855);
  3097. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3098. tt_int_op(hour,OP_EQ, 3);
  3099. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3100. tt_int_op(min,OP_EQ, 14);
  3101. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3102. /* and 7 seconds - ignored */
  3103. /* INT32_MIN: check that we get the absolute value of interval,
  3104. * which doesn't actually fit in int32_t.
  3105. * We expect INT32_MAX or INT32_MAX + 1 with 64 bit longs */
  3106. format_time_interval(dbuf, sizeof(dbuf), -2147483647L - 1L);
  3107. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3108. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  3109. &day, label_d, &hour, label_h, &min, label_m);
  3110. tt_int_op(r,OP_EQ, 6);
  3111. tt_int_op(day,OP_EQ, 24855);
  3112. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3113. tt_int_op(hour,OP_EQ, 3);
  3114. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3115. tt_int_op(min,OP_EQ, 14);
  3116. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3117. /* and 7 or 8 seconds - ignored */
  3118. #endif /* SIZEOF_LONG == 4 || SIZEOF_LONG == 8 */
  3119. #if SIZEOF_LONG == 8
  3120. /* We can try INT64_MIN/MAX */
  3121. /* Always ignore second(s) */
  3122. /* INT64_MAX */
  3123. format_time_interval(dbuf, sizeof(dbuf), 9223372036854775807L);
  3124. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3125. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  3126. &day, label_d, &hour, label_h, &min, label_m);
  3127. tt_int_op(r,OP_EQ, 6);
  3128. tt_int_op(day,OP_EQ, 106751991167300L);
  3129. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3130. tt_int_op(hour,OP_EQ, 15);
  3131. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3132. tt_int_op(min,OP_EQ, 30);
  3133. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3134. /* and 7 seconds - ignored */
  3135. /* INT64_MIN: check that we get the absolute value of interval,
  3136. * which doesn't actually fit in int64_t.
  3137. * We expect INT64_MAX */
  3138. format_time_interval(dbuf, sizeof(dbuf),
  3139. -9223372036854775807L - 1L);
  3140. tt_int_op(strnlen(dbuf, DBUF_SIZE),OP_LE, DBUF_SIZE - 1);
  3141. r = tor_sscanf(dbuf, TL_ " " TL_ " " TL_,
  3142. &day, label_d, &hour, label_h, &min, label_m);
  3143. tt_int_op(r,OP_EQ, 6);
  3144. tt_int_op(day,OP_EQ, 106751991167300L);
  3145. tt_ci_char_op(label_d[0],OP_EQ, 'd');
  3146. tt_int_op(hour,OP_EQ, 15);
  3147. tt_ci_char_op(label_h[0],OP_EQ, 'h');
  3148. tt_int_op(min,OP_EQ, 30);
  3149. tt_ci_char_op(label_m[0],OP_EQ, 'm');
  3150. /* and 7 or 8 seconds - ignored */
  3151. #endif /* SIZEOF_LONG == 8 */
  3152. done:
  3153. ;
  3154. }
  3155. #undef tt_char_op
  3156. #undef tt_ci_char_op
  3157. #undef DBUF_SIZE
  3158. #undef T_
  3159. #undef LABEL_SIZE
  3160. #undef L_
  3161. #undef TL_
  3162. static void
  3163. test_util_path_is_relative(void *arg)
  3164. {
  3165. /* OS-independent tests */
  3166. (void)arg;
  3167. tt_int_op(1,OP_EQ, path_is_relative(""));
  3168. tt_int_op(1,OP_EQ, path_is_relative("dir"));
  3169. tt_int_op(1,OP_EQ, path_is_relative("dir/"));
  3170. tt_int_op(1,OP_EQ, path_is_relative("./dir"));
  3171. tt_int_op(1,OP_EQ, path_is_relative("../dir"));
  3172. tt_int_op(0,OP_EQ, path_is_relative("/"));
  3173. tt_int_op(0,OP_EQ, path_is_relative("/dir"));
  3174. tt_int_op(0,OP_EQ, path_is_relative("/dir/"));
  3175. /* Windows */
  3176. #ifdef _WIN32
  3177. /* I don't have Windows so I can't test this, hence the "#ifdef
  3178. 0". These are tests that look useful, so please try to get them
  3179. running and uncomment if it all works as it should */
  3180. tt_int_op(1,OP_EQ, path_is_relative("dir"));
  3181. tt_int_op(1,OP_EQ, path_is_relative("dir\\"));
  3182. tt_int_op(1,OP_EQ, path_is_relative("dir\\a:"));
  3183. tt_int_op(1,OP_EQ, path_is_relative("dir\\a:\\"));
  3184. tt_int_op(1,OP_EQ, path_is_relative("http:\\dir"));
  3185. tt_int_op(0,OP_EQ, path_is_relative("\\dir"));
  3186. tt_int_op(0,OP_EQ, path_is_relative("a:\\dir"));
  3187. tt_int_op(0,OP_EQ, path_is_relative("z:\\dir"));
  3188. #endif /* defined(_WIN32) */
  3189. done:
  3190. ;
  3191. }
  3192. /** Run unittests for memory area allocator */
  3193. static void
  3194. test_util_memarea(void *arg)
  3195. {
  3196. memarea_t *area = memarea_new();
  3197. char *p1, *p2, *p3, *p1_orig;
  3198. void *malloced_ptr = NULL;
  3199. int i;
  3200. #ifdef DISABLE_MEMORY_SENTINELS
  3201. /* If memory sentinels are disabled, this whole module is just an alias for
  3202. malloc(), which is free to lay out memory most any way it wants. */
  3203. if (1)
  3204. tt_skip();
  3205. #endif /* defined(DISABLE_MEMORY_SENTINELS) */
  3206. (void)arg;
  3207. tt_assert(area);
  3208. p1_orig = p1 = memarea_alloc(area,64);
  3209. p2 = memarea_alloc_zero(area,52);
  3210. p3 = memarea_alloc(area,11);
  3211. tt_assert(memarea_owns_ptr(area, p1));
  3212. tt_assert(memarea_owns_ptr(area, p2));
  3213. tt_assert(memarea_owns_ptr(area, p3));
  3214. /* Make sure we left enough space. */
  3215. tt_assert(p1+64 <= p2);
  3216. tt_assert(p2+52 <= p3);
  3217. /* Make sure we aligned. */
  3218. tt_int_op(((uintptr_t)p1) % sizeof(void*),OP_EQ, 0);
  3219. tt_int_op(((uintptr_t)p2) % sizeof(void*),OP_EQ, 0);
  3220. tt_int_op(((uintptr_t)p3) % sizeof(void*),OP_EQ, 0);
  3221. tt_assert(!memarea_owns_ptr(area, p3+8192));
  3222. tt_assert(!memarea_owns_ptr(area, p3+30));
  3223. tt_assert(fast_mem_is_zero(p2, 52));
  3224. /* Make sure we don't overalign. */
  3225. p1 = memarea_alloc(area, 1);
  3226. p2 = memarea_alloc(area, 1);
  3227. tt_ptr_op(p1+sizeof(void*),OP_EQ, p2);
  3228. {
  3229. malloced_ptr = tor_malloc(64);
  3230. tt_assert(!memarea_owns_ptr(area, malloced_ptr));
  3231. tor_free(malloced_ptr);
  3232. }
  3233. /* memarea_memdup */
  3234. {
  3235. malloced_ptr = tor_malloc(64);
  3236. crypto_rand((char*)malloced_ptr, 64);
  3237. p1 = memarea_memdup(area, malloced_ptr, 64);
  3238. tt_assert(p1 != malloced_ptr);
  3239. tt_mem_op(p1,OP_EQ, malloced_ptr, 64);
  3240. tor_free(malloced_ptr);
  3241. }
  3242. /* memarea_strdup. */
  3243. p1 = memarea_strdup(area,"");
  3244. p2 = memarea_strdup(area, "abcd");
  3245. tt_assert(p1);
  3246. tt_assert(p2);
  3247. tt_str_op(p1,OP_EQ, "");
  3248. tt_str_op(p2,OP_EQ, "abcd");
  3249. /* memarea_strndup. */
  3250. {
  3251. const char *s = "Ad ogni porta batte la morte e grida: il nome!";
  3252. /* (From Turandot, act 3.) */
  3253. size_t len = strlen(s);
  3254. p1 = memarea_strndup(area, s, 1000);
  3255. p2 = memarea_strndup(area, s, 10);
  3256. tt_str_op(p1,OP_EQ, s);
  3257. tt_assert(p2 >= p1 + len + 1);
  3258. tt_mem_op(s,OP_EQ, p2, 10);
  3259. tt_int_op(p2[10],OP_EQ, '\0');
  3260. p3 = memarea_strndup(area, s, len);
  3261. tt_str_op(p3,OP_EQ, s);
  3262. p3 = memarea_strndup(area, s, len-1);
  3263. tt_mem_op(s,OP_EQ, p3, len-1);
  3264. tt_int_op(p3[len-1],OP_EQ, '\0');
  3265. }
  3266. memarea_clear(area);
  3267. p1 = memarea_alloc(area, 1);
  3268. tt_ptr_op(p1,OP_EQ, p1_orig);
  3269. memarea_clear(area);
  3270. size_t total = 0, initial_allocation, allocation2, dummy;
  3271. memarea_get_stats(area, &initial_allocation, &dummy);
  3272. /* Check for running over an area's size. */
  3273. for (i = 0; i < 4096; ++i) {
  3274. size_t n = crypto_rand_int(6);
  3275. p1 = memarea_alloc(area, n);
  3276. total += n;
  3277. tt_assert(memarea_owns_ptr(area, p1));
  3278. }
  3279. memarea_assert_ok(area);
  3280. memarea_get_stats(area, &allocation2, &dummy);
  3281. /* Make sure we can allocate a too-big object. */
  3282. p1 = memarea_alloc_zero(area, 9000);
  3283. p2 = memarea_alloc_zero(area, 16);
  3284. total += 9000;
  3285. total += 16;
  3286. tt_assert(memarea_owns_ptr(area, p1));
  3287. tt_assert(memarea_owns_ptr(area, p2));
  3288. /* Now test stats... */
  3289. size_t allocated = 0, used = 0;
  3290. memarea_get_stats(area, &allocated, &used);
  3291. tt_int_op(used, OP_LE, allocated);
  3292. tt_int_op(used, OP_GE, total); /* not EQ, because of alignment and headers*/
  3293. tt_int_op(allocated, OP_GT, allocation2);
  3294. tt_int_op(allocation2, OP_GT, initial_allocation);
  3295. memarea_clear(area);
  3296. memarea_get_stats(area, &allocated, &used);
  3297. tt_int_op(used, OP_LT, 128); /* Not 0, because of header */
  3298. tt_int_op(allocated, OP_EQ, initial_allocation);
  3299. done:
  3300. memarea_drop_all(area);
  3301. tor_free(malloced_ptr);
  3302. }
  3303. /** Run unit tests for utility functions to get file names relative to
  3304. * the data directory. */
  3305. static void
  3306. test_util_datadir(void *arg)
  3307. {
  3308. char buf[1024];
  3309. char *f = NULL;
  3310. char *temp_dir = NULL;
  3311. (void)arg;
  3312. temp_dir = get_datadir_fname(NULL);
  3313. f = get_datadir_fname("state");
  3314. tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"state", temp_dir);
  3315. tt_str_op(f,OP_EQ, buf);
  3316. tor_free(f);
  3317. f = get_datadir_fname2("cache", "thingy");
  3318. tor_snprintf(buf, sizeof(buf),
  3319. "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy", temp_dir);
  3320. tt_str_op(f,OP_EQ, buf);
  3321. tor_free(f);
  3322. f = get_datadir_fname2_suffix("cache", "thingy", ".foo");
  3323. tor_snprintf(buf, sizeof(buf),
  3324. "%s"PATH_SEPARATOR"cache"PATH_SEPARATOR"thingy.foo", temp_dir);
  3325. tt_str_op(f,OP_EQ, buf);
  3326. tor_free(f);
  3327. f = get_datadir_fname_suffix("cache", ".foo");
  3328. tor_snprintf(buf, sizeof(buf), "%s"PATH_SEPARATOR"cache.foo",
  3329. temp_dir);
  3330. tt_str_op(f,OP_EQ, buf);
  3331. done:
  3332. tor_free(f);
  3333. tor_free(temp_dir);
  3334. }
  3335. static void
  3336. test_util_strtok(void *arg)
  3337. {
  3338. char buf[128];
  3339. char buf2[128];
  3340. int i;
  3341. char *cp1, *cp2;
  3342. (void)arg;
  3343. for (i = 0; i < 3; i++) {
  3344. const char *pad1="", *pad2="";
  3345. switch (i) {
  3346. case 0:
  3347. break;
  3348. case 1:
  3349. pad1 = " ";
  3350. pad2 = "!";
  3351. break;
  3352. case 2:
  3353. pad1 = " ";
  3354. pad2 = ";!";
  3355. break;
  3356. }
  3357. tor_snprintf(buf, sizeof(buf), "%s", pad1);
  3358. tor_snprintf(buf2, sizeof(buf2), "%s", pad2);
  3359. tt_ptr_op(tor_strtok_r_impl(buf, " ", &cp1), OP_EQ, NULL);
  3360. tt_ptr_op(tor_strtok_r_impl(buf2, ".!..;!", &cp2), OP_EQ, NULL);
  3361. tor_snprintf(buf, sizeof(buf),
  3362. "%sGraved on the dark in gestures of descent%s", pad1, pad1);
  3363. tor_snprintf(buf2, sizeof(buf2),
  3364. "%sthey.seemed;;their!.own;most.perfect;monument%s",pad2,pad2);
  3365. /* -- "Year's End", Richard Wilbur */
  3366. tt_str_op("Graved",OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  3367. tt_str_op("they",OP_EQ, tor_strtok_r_impl(buf2, ".!..;!", &cp2));
  3368. #define S1() tor_strtok_r_impl(NULL, " ", &cp1)
  3369. #define S2() tor_strtok_r_impl(NULL, ".!..;!", &cp2)
  3370. tt_str_op("on",OP_EQ, S1());
  3371. tt_str_op("the",OP_EQ, S1());
  3372. tt_str_op("dark",OP_EQ, S1());
  3373. tt_str_op("seemed",OP_EQ, S2());
  3374. tt_str_op("their",OP_EQ, S2());
  3375. tt_str_op("own",OP_EQ, S2());
  3376. tt_str_op("in",OP_EQ, S1());
  3377. tt_str_op("gestures",OP_EQ, S1());
  3378. tt_str_op("of",OP_EQ, S1());
  3379. tt_str_op("most",OP_EQ, S2());
  3380. tt_str_op("perfect",OP_EQ, S2());
  3381. tt_str_op("descent",OP_EQ, S1());
  3382. tt_str_op("monument",OP_EQ, S2());
  3383. tt_ptr_op(NULL,OP_EQ, S1());
  3384. tt_ptr_op(NULL,OP_EQ, S2());
  3385. }
  3386. buf[0] = 0;
  3387. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  3388. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, "!", &cp1));
  3389. strlcpy(buf, "Howdy!", sizeof(buf));
  3390. tt_str_op("Howdy",OP_EQ, tor_strtok_r_impl(buf, "!", &cp1));
  3391. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(NULL, "!", &cp1));
  3392. strlcpy(buf, " ", sizeof(buf));
  3393. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  3394. strlcpy(buf, " ", sizeof(buf));
  3395. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  3396. strlcpy(buf, "something ", sizeof(buf));
  3397. tt_str_op("something",OP_EQ, tor_strtok_r_impl(buf, " ", &cp1));
  3398. tt_ptr_op(NULL,OP_EQ, tor_strtok_r_impl(NULL, ";", &cp1));
  3399. done:
  3400. ;
  3401. }
  3402. static void
  3403. test_util_find_str_at_start_of_line(void *ptr)
  3404. {
  3405. const char *long_string =
  3406. "howdy world. how are you? i hope it's fine.\n"
  3407. "hello kitty\n"
  3408. "third line";
  3409. char *line2 = strchr(long_string,'\n')+1;
  3410. char *line3 = strchr(line2,'\n')+1;
  3411. const char *short_string = "hello kitty\n"
  3412. "second line\n";
  3413. char *short_line2 = strchr(short_string,'\n')+1;
  3414. (void)ptr;
  3415. tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, ""));
  3416. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(short_string, "nonsense"));
  3417. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "nonsense"));
  3418. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "\n"));
  3419. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "how "));
  3420. tt_ptr_op(NULL,OP_EQ, find_str_at_start_of_line(long_string, "kitty"));
  3421. tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, "h"));
  3422. tt_ptr_op(long_string,OP_EQ, find_str_at_start_of_line(long_string, "how"));
  3423. tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "he"));
  3424. tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "hell"));
  3425. tt_ptr_op(line2,OP_EQ, find_str_at_start_of_line(long_string, "hello k"));
  3426. tt_ptr_op(line2,OP_EQ,
  3427. find_str_at_start_of_line(long_string, "hello kitty\n"));
  3428. tt_ptr_op(line2,OP_EQ,
  3429. find_str_at_start_of_line(long_string, "hello kitty\nt"));
  3430. tt_ptr_op(line3,OP_EQ, find_str_at_start_of_line(long_string, "third"));
  3431. tt_ptr_op(line3,OP_EQ, find_str_at_start_of_line(long_string, "third line"));
  3432. tt_ptr_op(NULL, OP_EQ,
  3433. find_str_at_start_of_line(long_string, "third line\n"));
  3434. tt_ptr_op(short_line2,OP_EQ, find_str_at_start_of_line(short_string,
  3435. "second line\n"));
  3436. done:
  3437. ;
  3438. }
  3439. static void
  3440. test_util_string_is_C_identifier(void *ptr)
  3441. {
  3442. (void)ptr;
  3443. tt_int_op(1,OP_EQ, string_is_C_identifier("string_is_C_identifier"));
  3444. tt_int_op(1,OP_EQ, string_is_C_identifier("_string_is_C_identifier"));
  3445. tt_int_op(1,OP_EQ, string_is_C_identifier("_"));
  3446. tt_int_op(1,OP_EQ, string_is_C_identifier("i"));
  3447. tt_int_op(1,OP_EQ, string_is_C_identifier("_____"));
  3448. tt_int_op(1,OP_EQ, string_is_C_identifier("__00__"));
  3449. tt_int_op(1,OP_EQ, string_is_C_identifier("__init__"));
  3450. tt_int_op(1,OP_EQ, string_is_C_identifier("_0"));
  3451. tt_int_op(1,OP_EQ, string_is_C_identifier("_0string_is_C_identifier"));
  3452. tt_int_op(1,OP_EQ, string_is_C_identifier("_0"));
  3453. tt_int_op(0,OP_EQ, string_is_C_identifier("0_string_is_C_identifier"));
  3454. tt_int_op(0,OP_EQ, string_is_C_identifier("0"));
  3455. tt_int_op(0,OP_EQ, string_is_C_identifier(""));
  3456. tt_int_op(0,OP_EQ, string_is_C_identifier(";"));
  3457. tt_int_op(0,OP_EQ, string_is_C_identifier("i;"));
  3458. tt_int_op(0,OP_EQ, string_is_C_identifier("_;"));
  3459. tt_int_op(0,OP_EQ, string_is_C_identifier("í"));
  3460. tt_int_op(0,OP_EQ, string_is_C_identifier("ñ"));
  3461. done:
  3462. ;
  3463. }
  3464. static void
  3465. test_util_string_is_utf8(void *ptr)
  3466. {
  3467. (void)ptr;
  3468. tt_int_op(1, OP_EQ, string_is_utf8(NULL, 0));
  3469. tt_int_op(1, OP_EQ, string_is_utf8("", 1));
  3470. tt_int_op(1, OP_EQ, string_is_utf8("\uFEFF", 3));
  3471. tt_int_op(1, OP_EQ, string_is_utf8("\uFFFE", 3));
  3472. tt_int_op(1, OP_EQ, string_is_utf8("ascii\x7f\n", 7));
  3473. tt_int_op(1, OP_EQ, string_is_utf8("Risqu\u00e9=1", 9));
  3474. /* Test the utf8_no_bom function */
  3475. tt_int_op(0, OP_EQ, string_is_utf8_no_bom("\uFEFF", 3));
  3476. tt_int_op(0, OP_EQ, string_is_utf8_no_bom("\uFFFE", 3));
  3477. tt_int_op(0, OP_EQ, string_is_utf8_no_bom("\uFEFFlove", 7));
  3478. tt_int_op(1, OP_EQ, string_is_utf8_no_bom("loveandrespect",
  3479. strlen("loveandrespect")));
  3480. // Validate exactly 'len' bytes.
  3481. tt_int_op(0, OP_EQ, string_is_utf8("\0\x80", 2));
  3482. tt_int_op(0, OP_EQ, string_is_utf8("Risqu\u00e9=1", 6));
  3483. // Reject sequences with missing bytes.
  3484. tt_int_op(0, OP_EQ, string_is_utf8("\x80", 1));
  3485. tt_int_op(0, OP_EQ, string_is_utf8("\xc2", 1));
  3486. tt_int_op(0, OP_EQ, string_is_utf8("\xc2 ", 2));
  3487. tt_int_op(0, OP_EQ, string_is_utf8("\xe1\x80", 2));
  3488. tt_int_op(0, OP_EQ, string_is_utf8("\xe1\x80 ", 3));
  3489. tt_int_op(0, OP_EQ, string_is_utf8("\xf1\x80\x80", 3));
  3490. tt_int_op(0, OP_EQ, string_is_utf8("\xf1\x80\x80 ", 4));
  3491. // Reject encodings that are overly long.
  3492. tt_int_op(0, OP_EQ, string_is_utf8("\xc1\xbf", 2));
  3493. tt_int_op(1, OP_EQ, string_is_utf8("\xc2\x80", 2));
  3494. tt_int_op(0, OP_EQ, string_is_utf8("\xe0\x9f\xbf", 3));
  3495. tt_int_op(1, OP_EQ, string_is_utf8("\xe0\xa0\x80", 3));
  3496. tt_int_op(0, OP_EQ, string_is_utf8("\xf0\x8f\xbf\xbf", 4));
  3497. tt_int_op(1, OP_EQ, string_is_utf8("\xf0\x90\x80\x80", 4));
  3498. // Reject UTF-16 surrogate halves.
  3499. tt_int_op(1, OP_EQ, string_is_utf8("\xed\x9f\xbf", 3));
  3500. tt_int_op(0, OP_EQ, string_is_utf8("\xed\xa0\x80", 3));
  3501. tt_int_op(0, OP_EQ, string_is_utf8("\xed\xbf\xbf", 3));
  3502. tt_int_op(1, OP_EQ, string_is_utf8("\xee\x80\x80", 3));
  3503. // The maximum legal codepoint, 10FFFF.
  3504. tt_int_op(1, OP_EQ, string_is_utf8("\xf4\x8f\xbf\xbf", 4));
  3505. tt_int_op(0, OP_EQ, string_is_utf8("\xf4\x90\x80\x80", 4));
  3506. done:
  3507. ;
  3508. }
  3509. static void
  3510. test_util_asprintf(void *ptr)
  3511. {
  3512. #define LOREMIPSUM \
  3513. "Lorem ipsum dolor sit amet, consectetur adipisicing elit"
  3514. char *cp=NULL, *cp2=NULL;
  3515. int r;
  3516. (void)ptr;
  3517. /* simple string */
  3518. r = tor_asprintf(&cp, "simple string 100%% safe");
  3519. tt_assert(cp);
  3520. tt_str_op("simple string 100% safe",OP_EQ, cp);
  3521. tt_int_op(strlen(cp),OP_EQ, r);
  3522. tor_free(cp);
  3523. /* empty string */
  3524. r = tor_asprintf(&cp, "%s", "");
  3525. tt_assert(cp);
  3526. tt_str_op("",OP_EQ, cp);
  3527. tt_int_op(strlen(cp),OP_EQ, r);
  3528. tor_free(cp);
  3529. /* numbers (%i) */
  3530. r = tor_asprintf(&cp, "I like numbers-%2i, %i, etc.", -1, 2);
  3531. tt_assert(cp);
  3532. tt_str_op("I like numbers--1, 2, etc.",OP_EQ, cp);
  3533. tt_int_op(strlen(cp),OP_EQ, r);
  3534. /* don't free cp; next test uses it. */
  3535. /* numbers (%d) */
  3536. r = tor_asprintf(&cp2, "First=%d, Second=%d", 101, 202);
  3537. tt_assert(cp2);
  3538. tt_int_op(strlen(cp2),OP_EQ, r);
  3539. tt_str_op("First=101, Second=202",OP_EQ, cp2);
  3540. tt_assert(cp != cp2);
  3541. tor_free(cp);
  3542. tor_free(cp2);
  3543. /* Glass-box test: a string exactly 128 characters long. */
  3544. r = tor_asprintf(&cp, "Lorem1: %sLorem2: %s", LOREMIPSUM, LOREMIPSUM);
  3545. tt_assert(cp);
  3546. tt_int_op(128,OP_EQ, r);
  3547. tt_int_op(cp[128], OP_EQ, '\0');
  3548. tt_str_op("Lorem1: "LOREMIPSUM"Lorem2: "LOREMIPSUM,OP_EQ, cp);
  3549. tor_free(cp);
  3550. /* String longer than 128 characters */
  3551. r = tor_asprintf(&cp, "1: %s 2: %s 3: %s",
  3552. LOREMIPSUM, LOREMIPSUM, LOREMIPSUM);
  3553. tt_assert(cp);
  3554. tt_int_op(strlen(cp),OP_EQ, r);
  3555. tt_str_op("1: "LOREMIPSUM" 2: "LOREMIPSUM" 3: "LOREMIPSUM,OP_EQ, cp);
  3556. done:
  3557. tor_free(cp);
  3558. tor_free(cp2);
  3559. }
  3560. static void
  3561. test_util_listdir(void *ptr)
  3562. {
  3563. smartlist_t *dir_contents = NULL;
  3564. char *fname1=NULL, *fname2=NULL, *fname3=NULL, *dir1=NULL, *dirname=NULL;
  3565. int r;
  3566. (void)ptr;
  3567. fname1 = tor_strdup(get_fname("hopscotch"));
  3568. fname2 = tor_strdup(get_fname("mumblety-peg"));
  3569. fname3 = tor_strdup(get_fname(".hidden-file"));
  3570. dir1 = tor_strdup(get_fname("some-directory"));
  3571. dirname = tor_strdup(get_fname(NULL));
  3572. tt_int_op(0,OP_EQ, write_str_to_file(fname1, "X\n", 0));
  3573. tt_int_op(0,OP_EQ, write_str_to_file(fname2, "Y\n", 0));
  3574. tt_int_op(0,OP_EQ, write_str_to_file(fname3, "Z\n", 0));
  3575. #ifdef _WIN32
  3576. r = mkdir(dir1);
  3577. #else
  3578. r = mkdir(dir1, 0700);
  3579. #endif
  3580. if (r) {
  3581. fprintf(stderr, "Can't create directory %s:", dir1);
  3582. perror("");
  3583. exit(1);
  3584. }
  3585. dir_contents = tor_listdir(dirname);
  3586. tt_assert(dir_contents);
  3587. /* make sure that each filename is listed. */
  3588. tt_assert(smartlist_contains_string_case(dir_contents, "hopscotch"));
  3589. tt_assert(smartlist_contains_string_case(dir_contents, "mumblety-peg"));
  3590. tt_assert(smartlist_contains_string_case(dir_contents, ".hidden-file"));
  3591. tt_assert(smartlist_contains_string_case(dir_contents, "some-directory"));
  3592. tt_assert(!smartlist_contains_string(dir_contents, "."));
  3593. tt_assert(!smartlist_contains_string(dir_contents, ".."));
  3594. done:
  3595. tor_free(fname1);
  3596. tor_free(fname2);
  3597. tor_free(fname3);
  3598. tor_free(dir1);
  3599. tor_free(dirname);
  3600. if (dir_contents) {
  3601. SMARTLIST_FOREACH(dir_contents, char *, cp, tor_free(cp));
  3602. smartlist_free(dir_contents);
  3603. }
  3604. }
  3605. static void
  3606. test_util_parent_dir(void *ptr)
  3607. {
  3608. char *cp;
  3609. (void)ptr;
  3610. #define T(output,expect_ok,input) \
  3611. do { \
  3612. int ok; \
  3613. cp = tor_strdup(input); \
  3614. ok = get_parent_directory(cp); \
  3615. tt_int_op(expect_ok, OP_EQ, ok); \
  3616. if (ok==0) \
  3617. tt_str_op(output, OP_EQ, cp); \
  3618. tor_free(cp); \
  3619. } while (0);
  3620. T("/home/wombat", 0, "/home/wombat/knish");
  3621. T("/home/wombat", 0, "/home/wombat/knish/");
  3622. T("/home/wombat", 0, "/home/wombat/knish///");
  3623. T("./home/wombat", 0, "./home/wombat/knish/");
  3624. T("/", 0, "/home");
  3625. T("/", 0, "/home//");
  3626. T(".", 0, "./wombat");
  3627. T(".", 0, "./wombat/");
  3628. T(".", 0, "./wombat//");
  3629. T("wombat", 0, "wombat/foo");
  3630. T("wombat/..", 0, "wombat/../foo");
  3631. T("wombat/../", 0, "wombat/..//foo"); /* Is this correct? */
  3632. T("wombat/.", 0, "wombat/./foo");
  3633. T("wombat/./", 0, "wombat/.//foo"); /* Is this correct? */
  3634. T("wombat", 0, "wombat/..//");
  3635. T("wombat", 0, "wombat/foo/");
  3636. T("wombat", 0, "wombat/.foo");
  3637. T("wombat", 0, "wombat/.foo/");
  3638. T("wombat", -1, "");
  3639. T("w", -1, "");
  3640. T("wombat", 0, "wombat/knish");
  3641. T("/", 0, "/");
  3642. T("/", 0, "////");
  3643. done:
  3644. tor_free(cp);
  3645. }
  3646. static void
  3647. test_util_ftruncate(void *ptr)
  3648. {
  3649. char *buf = NULL;
  3650. const char *fname;
  3651. int fd = -1;
  3652. const char *message = "Hello world";
  3653. const char *message2 = "Hola mundo";
  3654. struct stat st;
  3655. (void) ptr;
  3656. fname = get_fname("ftruncate");
  3657. fd = tor_open_cloexec(fname, O_WRONLY|O_CREAT, 0600);
  3658. tt_int_op(fd, OP_GE, 0);
  3659. /* Make the file be there. */
  3660. tt_int_op(strlen(message), OP_EQ,
  3661. write_all_to_fd(fd, message, strlen(message)));
  3662. tt_int_op((int)tor_fd_getpos(fd), OP_EQ, strlen(message));
  3663. tt_int_op(0, OP_EQ, fstat(fd, &st));
  3664. tt_int_op((int)st.st_size, OP_EQ, strlen(message));
  3665. /* Truncate and see if it got truncated */
  3666. tt_int_op(0, OP_EQ, tor_ftruncate(fd));
  3667. tt_int_op((int)tor_fd_getpos(fd), OP_EQ, 0);
  3668. tt_int_op(0, OP_EQ, fstat(fd, &st));
  3669. tt_int_op((int)st.st_size, OP_EQ, 0);
  3670. /* Replace, and see if it got replaced */
  3671. tt_int_op(strlen(message2), OP_EQ,
  3672. write_all_to_fd(fd, message2, strlen(message2)));
  3673. tt_int_op((int)tor_fd_getpos(fd), OP_EQ, strlen(message2));
  3674. tt_int_op(0, OP_EQ, fstat(fd, &st));
  3675. tt_int_op((int)st.st_size, OP_EQ, strlen(message2));
  3676. close(fd);
  3677. fd = -1;
  3678. buf = read_file_to_str(fname, 0, NULL);
  3679. tt_str_op(message2, OP_EQ, buf);
  3680. done:
  3681. if (fd >= 0)
  3682. close(fd);
  3683. tor_free(buf);
  3684. }
  3685. static void
  3686. test_util_num_cpus(void *arg)
  3687. {
  3688. (void)arg;
  3689. int num = compute_num_cpus();
  3690. if (num < 0)
  3691. tt_skip();
  3692. tt_int_op(num, OP_GE, 1);
  3693. tt_int_op(num, OP_LE, 16);
  3694. done:
  3695. ;
  3696. }
  3697. #ifdef _WIN32
  3698. static void
  3699. test_util_load_win_lib(void *ptr)
  3700. {
  3701. HANDLE h = load_windows_system_library(_T("advapi32.dll"));
  3702. (void) ptr;
  3703. tt_assert(h);
  3704. done:
  3705. if (h)
  3706. FreeLibrary(h);
  3707. }
  3708. #endif /* defined(_WIN32) */
  3709. /**
  3710. * Test for format_hex_number_sigsafe()
  3711. */
  3712. static void
  3713. test_util_format_hex_number(void *ptr)
  3714. {
  3715. int i, len;
  3716. char buf[33];
  3717. const struct {
  3718. const char *str;
  3719. unsigned int x;
  3720. } test_data[] = {
  3721. {"0", 0},
  3722. {"1", 1},
  3723. {"273A", 0x273a},
  3724. {"FFFF", 0xffff},
  3725. {"7FFFFFFF", 0x7fffffff},
  3726. {"FFFFFFFF", 0xffffffff},
  3727. #if UINT_MAX >= 0xffffffff
  3728. {"31BC421D", 0x31bc421d},
  3729. {"FFFFFFFF", 0xffffffff},
  3730. #endif
  3731. {NULL, 0}
  3732. };
  3733. (void)ptr;
  3734. for (i = 0; test_data[i].str != NULL; ++i) {
  3735. len = format_hex_number_sigsafe(test_data[i].x, buf, sizeof(buf));
  3736. tt_int_op(len,OP_NE, 0);
  3737. tt_int_op(len,OP_EQ, strlen(buf));
  3738. tt_str_op(buf,OP_EQ, test_data[i].str);
  3739. }
  3740. tt_int_op(4,OP_EQ, format_hex_number_sigsafe(0xffff, buf, 5));
  3741. tt_str_op(buf,OP_EQ, "FFFF");
  3742. tt_int_op(0,OP_EQ, format_hex_number_sigsafe(0xffff, buf, 4));
  3743. tt_int_op(0,OP_EQ, format_hex_number_sigsafe(0, buf, 1));
  3744. done:
  3745. return;
  3746. }
  3747. /**
  3748. * Test for format_hex_number_sigsafe()
  3749. */
  3750. static void
  3751. test_util_format_dec_number(void *ptr)
  3752. {
  3753. int i, len;
  3754. char buf[33];
  3755. const struct {
  3756. const char *str;
  3757. unsigned int x;
  3758. } test_data[] = {
  3759. {"0", 0},
  3760. {"1", 1},
  3761. {"1234", 1234},
  3762. {"12345678", 12345678},
  3763. {"99999999", 99999999},
  3764. {"100000000", 100000000},
  3765. {"4294967295", 4294967295u},
  3766. #if UINT_MAX > 0xffffffff
  3767. {"18446744073709551615", 18446744073709551615u },
  3768. #endif
  3769. {NULL, 0}
  3770. };
  3771. (void)ptr;
  3772. for (i = 0; test_data[i].str != NULL; ++i) {
  3773. len = format_dec_number_sigsafe(test_data[i].x, buf, sizeof(buf));
  3774. tt_int_op(len,OP_NE, 0);
  3775. tt_int_op(len,OP_EQ, strlen(buf));
  3776. tt_str_op(buf,OP_EQ, test_data[i].str);
  3777. len = format_dec_number_sigsafe(test_data[i].x, buf,
  3778. (int)(strlen(test_data[i].str) + 1));
  3779. tt_int_op(len,OP_EQ, strlen(buf));
  3780. tt_str_op(buf,OP_EQ, test_data[i].str);
  3781. }
  3782. tt_int_op(4,OP_EQ, format_dec_number_sigsafe(7331, buf, 5));
  3783. tt_str_op(buf,OP_EQ, "7331");
  3784. tt_int_op(0,OP_EQ, format_dec_number_sigsafe(7331, buf, 4));
  3785. tt_int_op(1,OP_EQ, format_dec_number_sigsafe(0, buf, 2));
  3786. tt_int_op(0,OP_EQ, format_dec_number_sigsafe(0, buf, 1));
  3787. done:
  3788. return;
  3789. }
  3790. #define MAX_SPLIT_LINE_COUNT 4
  3791. struct split_lines_test_t {
  3792. const char *orig_line; // Line to be split (may contain \0's)
  3793. int orig_length; // Length of orig_line
  3794. const char *split_line[MAX_SPLIT_LINE_COUNT]; // Split lines
  3795. };
  3796. static void
  3797. test_util_di_ops(void *arg)
  3798. {
  3799. #define LT -1
  3800. #define GT 1
  3801. #define EQ 0
  3802. const struct {
  3803. const char *a; int want_sign; const char *b;
  3804. } examples[] = {
  3805. { "Foo", EQ, "Foo" },
  3806. { "foo", GT, "bar", },
  3807. { "foobar", EQ ,"foobar" },
  3808. { "foobar", LT, "foobaw" },
  3809. { "foobar", GT, "f00bar" },
  3810. { "foobar", GT, "boobar" },
  3811. { "", EQ, "" },
  3812. { NULL, 0, NULL },
  3813. };
  3814. int i;
  3815. (void)arg;
  3816. for (i = 0; examples[i].a; ++i) {
  3817. size_t len = strlen(examples[i].a);
  3818. int eq1, eq2, neq1, neq2, cmp1, cmp2;
  3819. tt_int_op(len,OP_EQ, strlen(examples[i].b));
  3820. /* We do all of the operations, with operands in both orders. */
  3821. eq1 = tor_memeq(examples[i].a, examples[i].b, len);
  3822. eq2 = tor_memeq(examples[i].b, examples[i].a, len);
  3823. neq1 = tor_memneq(examples[i].a, examples[i].b, len);
  3824. neq2 = tor_memneq(examples[i].b, examples[i].a, len);
  3825. cmp1 = tor_memcmp(examples[i].a, examples[i].b, len);
  3826. cmp2 = tor_memcmp(examples[i].b, examples[i].a, len);
  3827. /* Check for correctness of cmp1 */
  3828. if (cmp1 < 0 && examples[i].want_sign != LT)
  3829. TT_DIE(("Assertion failed."));
  3830. else if (cmp1 > 0 && examples[i].want_sign != GT)
  3831. TT_DIE(("Assertion failed."));
  3832. else if (cmp1 == 0 && examples[i].want_sign != EQ)
  3833. TT_DIE(("Assertion failed."));
  3834. /* Check for consistency of everything else with cmp1 */
  3835. tt_int_op(eq1,OP_EQ, eq2);
  3836. tt_int_op(neq1,OP_EQ, neq2);
  3837. tt_int_op(cmp1,OP_EQ, -cmp2);
  3838. tt_int_op(eq1,OP_EQ, cmp1 == 0);
  3839. tt_int_op(neq1,OP_EQ, !eq1);
  3840. }
  3841. {
  3842. uint8_t zz = 0;
  3843. uint8_t ii = 0;
  3844. int z;
  3845. /* exhaustively test tor_memeq and tor_memcmp
  3846. * against each possible single-byte numeric difference
  3847. * some arithmetic bugs only appear with certain bit patterns */
  3848. for (z = 0; z < 256; z++) {
  3849. for (i = 0; i < 256; i++) {
  3850. ii = (uint8_t)i;
  3851. zz = (uint8_t)z;
  3852. tt_int_op(tor_memeq(&zz, &ii, 1),OP_EQ, zz == ii);
  3853. tt_int_op(tor_memcmp(&zz, &ii, 1) > 0 ? GT : EQ,OP_EQ,
  3854. zz > ii ? GT : EQ);
  3855. tt_int_op(tor_memcmp(&ii, &zz, 1) < 0 ? LT : EQ,OP_EQ,
  3856. ii < zz ? LT : EQ);
  3857. }
  3858. }
  3859. }
  3860. tt_int_op(1, OP_EQ, safe_mem_is_zero("", 0));
  3861. tt_int_op(1, OP_EQ, safe_mem_is_zero("", 1));
  3862. tt_int_op(0, OP_EQ, safe_mem_is_zero("a", 1));
  3863. tt_int_op(0, OP_EQ, safe_mem_is_zero("a", 2));
  3864. tt_int_op(0, OP_EQ, safe_mem_is_zero("\0a", 2));
  3865. tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0a", 2));
  3866. tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0", 8));
  3867. tt_int_op(1, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 8));
  3868. tt_int_op(0, OP_EQ, safe_mem_is_zero("\0\0\0\0\0\0\0\0a", 9));
  3869. done:
  3870. ;
  3871. }
  3872. static void
  3873. test_util_di_map(void *arg)
  3874. {
  3875. (void)arg;
  3876. di_digest256_map_t *dimap = NULL;
  3877. uint8_t key1[] = "Robert Anton Wilson ";
  3878. uint8_t key2[] = "Martin Gardner, _Fads&fallacies";
  3879. uint8_t key3[] = "Tom Lehrer, _Be Prepared_. ";
  3880. uint8_t key4[] = "Ursula Le Guin,_A Wizard of... ";
  3881. char dflt_entry[] = "'You have made a good beginning', but no more";
  3882. tt_int_op(32, OP_EQ, sizeof(key1));
  3883. tt_int_op(32, OP_EQ, sizeof(key2));
  3884. tt_int_op(32, OP_EQ, sizeof(key3));
  3885. tt_ptr_op(dflt_entry, OP_EQ, dimap_search(dimap, key1, dflt_entry));
  3886. char *str1 = tor_strdup("You are precisely as big as what you love"
  3887. " and precisely as small as what you allow"
  3888. " to annoy you.");
  3889. char *str2 = tor_strdup("Let us hope that Lysenko's success in Russia will"
  3890. " serve for many generations to come as another"
  3891. " reminder to the world of how quickly and easily"
  3892. " a science can be corrupted when ignorant"
  3893. " political leaders deem themselves competent"
  3894. " to arbitrate scientific disputes");
  3895. char *str3 = tor_strdup("Don't write naughty words on walls "
  3896. "if you can't spell.");
  3897. dimap_add_entry(&dimap, key1, str1);
  3898. dimap_add_entry(&dimap, key2, str2);
  3899. dimap_add_entry(&dimap, key3, str3);
  3900. tt_ptr_op(str1, OP_EQ, dimap_search(dimap, key1, dflt_entry));
  3901. tt_ptr_op(str3, OP_EQ, dimap_search(dimap, key3, dflt_entry));
  3902. tt_ptr_op(str2, OP_EQ, dimap_search(dimap, key2, dflt_entry));
  3903. tt_ptr_op(dflt_entry, OP_EQ, dimap_search(dimap, key4, dflt_entry));
  3904. done:
  3905. dimap_free(dimap, tor_free_);
  3906. }
  3907. /**
  3908. * Test counting high bits
  3909. */
  3910. static void
  3911. test_util_n_bits_set(void *ptr)
  3912. {
  3913. (void)ptr;
  3914. tt_int_op(0,OP_EQ, n_bits_set_u8(0));
  3915. tt_int_op(1,OP_EQ, n_bits_set_u8(1));
  3916. tt_int_op(3,OP_EQ, n_bits_set_u8(7));
  3917. tt_int_op(1,OP_EQ, n_bits_set_u8(8));
  3918. tt_int_op(2,OP_EQ, n_bits_set_u8(129));
  3919. tt_int_op(8,OP_EQ, n_bits_set_u8(255));
  3920. done:
  3921. ;
  3922. }
  3923. /**
  3924. * Test LHS whitespace (and comment) eater
  3925. */
  3926. static void
  3927. test_util_eat_whitespace(void *ptr)
  3928. {
  3929. const char ws[] = { ' ', '\t', '\r' }; /* Except NL */
  3930. char str[80];
  3931. size_t i;
  3932. (void)ptr;
  3933. /* Try one leading ws */
  3934. strlcpy(str, "fuubaar", sizeof(str));
  3935. for (i = 0; i < sizeof(ws); ++i) {
  3936. str[0] = ws[i];
  3937. tt_ptr_op(str + 1,OP_EQ, eat_whitespace(str));
  3938. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
  3939. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_no_nl(str));
  3940. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3941. }
  3942. str[0] = '\n';
  3943. tt_ptr_op(str + 1,OP_EQ, eat_whitespace(str));
  3944. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
  3945. tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
  3946. tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3947. /* Empty string */
  3948. strlcpy(str, "", sizeof(str));
  3949. tt_ptr_op(str,OP_EQ, eat_whitespace(str));
  3950. tt_ptr_op(str,OP_EQ, eat_whitespace_eos(str, str));
  3951. tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
  3952. tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str));
  3953. /* Only ws */
  3954. strlcpy(str, " \t\r\n", sizeof(str));
  3955. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
  3956. tt_ptr_op(str + strlen(str),OP_EQ,
  3957. eat_whitespace_eos(str, str + strlen(str)));
  3958. tt_ptr_op(str + strlen(str) - 1,OP_EQ,
  3959. eat_whitespace_no_nl(str));
  3960. tt_ptr_op(str + strlen(str) - 1,OP_EQ,
  3961. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3962. strlcpy(str, " \t\r ", sizeof(str));
  3963. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
  3964. tt_ptr_op(str + strlen(str),OP_EQ,
  3965. eat_whitespace_eos(str, str + strlen(str)));
  3966. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace_no_nl(str));
  3967. tt_ptr_op(str + strlen(str),OP_EQ,
  3968. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3969. /* Multiple ws */
  3970. strlcpy(str, "fuubaar", sizeof(str));
  3971. for (i = 0; i < sizeof(ws); ++i)
  3972. str[i] = ws[i];
  3973. tt_ptr_op(str + sizeof(ws),OP_EQ, eat_whitespace(str));
  3974. tt_ptr_op(str + sizeof(ws),OP_EQ,
  3975. eat_whitespace_eos(str, str + strlen(str)));
  3976. tt_ptr_op(str + sizeof(ws),OP_EQ, eat_whitespace_no_nl(str));
  3977. tt_ptr_op(str + sizeof(ws),OP_EQ,
  3978. eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3979. /* Eat comment */
  3980. strlcpy(str, "# Comment \n No Comment", sizeof(str));
  3981. tt_str_op("No Comment",OP_EQ, eat_whitespace(str));
  3982. tt_str_op("No Comment",OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
  3983. tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
  3984. tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3985. /* Eat comment & ws mix */
  3986. strlcpy(str, " # \t Comment \n\t\nNo Comment", sizeof(str));
  3987. tt_str_op("No Comment",OP_EQ, eat_whitespace(str));
  3988. tt_str_op("No Comment",OP_EQ, eat_whitespace_eos(str, str + strlen(str)));
  3989. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_no_nl(str));
  3990. tt_ptr_op(str + 1,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3991. /* Eat entire comment */
  3992. strlcpy(str, "#Comment", sizeof(str));
  3993. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
  3994. tt_ptr_op(str + strlen(str),OP_EQ,
  3995. eat_whitespace_eos(str, str + strlen(str)));
  3996. tt_ptr_op(str,OP_EQ, eat_whitespace_no_nl(str));
  3997. tt_ptr_op(str,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  3998. /* Blank line, then comment */
  3999. strlcpy(str, " \t\n # Comment", sizeof(str));
  4000. tt_ptr_op(str + strlen(str),OP_EQ, eat_whitespace(str));
  4001. tt_ptr_op(str + strlen(str),OP_EQ,
  4002. eat_whitespace_eos(str, str + strlen(str)));
  4003. tt_ptr_op(str + 2,OP_EQ, eat_whitespace_no_nl(str));
  4004. tt_ptr_op(str + 2,OP_EQ, eat_whitespace_eos_no_nl(str, str + strlen(str)));
  4005. done:
  4006. ;
  4007. }
  4008. /** Return a newly allocated smartlist containing the lines of text in
  4009. * <b>lines</b>. The returned strings are heap-allocated, and must be
  4010. * freed by the caller.
  4011. *
  4012. * XXXX? Move to container.[hc] ? */
  4013. static smartlist_t *
  4014. smartlist_new_from_text_lines(const char *lines)
  4015. {
  4016. smartlist_t *sl = smartlist_new();
  4017. char *last_line;
  4018. smartlist_split_string(sl, lines, "\n", 0, 0);
  4019. last_line = smartlist_pop_last(sl);
  4020. if (last_line != NULL && *last_line != '\0') {
  4021. smartlist_add(sl, last_line);
  4022. } else {
  4023. tor_free(last_line);
  4024. }
  4025. return sl;
  4026. }
  4027. /** Test smartlist_new_from_text_lines */
  4028. static void
  4029. test_util_sl_new_from_text_lines(void *ptr)
  4030. {
  4031. (void)ptr;
  4032. { /* Normal usage */
  4033. smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz\n");
  4034. int sl_len = smartlist_len(sl);
  4035. tt_want_int_op(sl_len, OP_EQ, 3);
  4036. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
  4037. if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), OP_EQ, "bar");
  4038. if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), OP_EQ, "baz");
  4039. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  4040. smartlist_free(sl);
  4041. }
  4042. { /* No final newline */
  4043. smartlist_t *sl = smartlist_new_from_text_lines("foo\nbar\nbaz");
  4044. int sl_len = smartlist_len(sl);
  4045. tt_want_int_op(sl_len, OP_EQ, 3);
  4046. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
  4047. if (sl_len > 1) tt_want_str_op(smartlist_get(sl, 1), OP_EQ, "bar");
  4048. if (sl_len > 2) tt_want_str_op(smartlist_get(sl, 2), OP_EQ, "baz");
  4049. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  4050. smartlist_free(sl);
  4051. }
  4052. { /* No newlines */
  4053. smartlist_t *sl = smartlist_new_from_text_lines("foo");
  4054. int sl_len = smartlist_len(sl);
  4055. tt_want_int_op(sl_len, OP_EQ, 1);
  4056. if (sl_len > 0) tt_want_str_op(smartlist_get(sl, 0), OP_EQ, "foo");
  4057. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  4058. smartlist_free(sl);
  4059. }
  4060. { /* No text at all */
  4061. smartlist_t *sl = smartlist_new_from_text_lines("");
  4062. int sl_len = smartlist_len(sl);
  4063. tt_want_int_op(sl_len, OP_EQ, 0);
  4064. SMARTLIST_FOREACH(sl, void *, x, tor_free(x));
  4065. smartlist_free(sl);
  4066. }
  4067. }
  4068. static void
  4069. test_util_envnames(void *ptr)
  4070. {
  4071. (void) ptr;
  4072. tt_assert(environment_variable_names_equal("abc", "abc"));
  4073. tt_assert(environment_variable_names_equal("abc", "abc="));
  4074. tt_assert(environment_variable_names_equal("abc", "abc=def"));
  4075. tt_assert(environment_variable_names_equal("abc=def", "abc"));
  4076. tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
  4077. tt_assert(environment_variable_names_equal("abc", "abc"));
  4078. tt_assert(environment_variable_names_equal("abc", "abc="));
  4079. tt_assert(environment_variable_names_equal("abc", "abc=def"));
  4080. tt_assert(environment_variable_names_equal("abc=def", "abc"));
  4081. tt_assert(environment_variable_names_equal("abc=def", "abc=ghi"));
  4082. tt_assert(!environment_variable_names_equal("abc", "abcd"));
  4083. tt_assert(!environment_variable_names_equal("abc=", "abcd"));
  4084. tt_assert(!environment_variable_names_equal("abc=", "abcd"));
  4085. tt_assert(!environment_variable_names_equal("abc=", "def"));
  4086. tt_assert(!environment_variable_names_equal("abc=", "def="));
  4087. tt_assert(!environment_variable_names_equal("abc=x", "def=x"));
  4088. tt_assert(!environment_variable_names_equal("", "a=def"));
  4089. /* A bit surprising. */
  4090. tt_assert(environment_variable_names_equal("", "=def"));
  4091. tt_assert(environment_variable_names_equal("=y", "=x"));
  4092. done:
  4093. ;
  4094. }
  4095. /** Test process_environment_make */
  4096. static void
  4097. test_util_make_environment(void *ptr)
  4098. {
  4099. const char *env_vars_string =
  4100. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  4101. "HOME=/home/foozer\n";
  4102. const char expected_windows_env_block[] =
  4103. "HOME=/home/foozer\000"
  4104. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\000"
  4105. "\000";
  4106. size_t expected_windows_env_block_len =
  4107. sizeof(expected_windows_env_block) - 1;
  4108. smartlist_t *env_vars = smartlist_new_from_text_lines(env_vars_string);
  4109. smartlist_t *env_vars_sorted = smartlist_new();
  4110. smartlist_t *env_vars_in_unixoid_env_block_sorted = smartlist_new();
  4111. process_environment_t *env;
  4112. (void)ptr;
  4113. env = process_environment_make(env_vars);
  4114. /* Check that the Windows environment block is correct. */
  4115. tt_want(tor_memeq(expected_windows_env_block, env->windows_environment_block,
  4116. expected_windows_env_block_len));
  4117. /* Now for the Unixoid environment block. We don't care which order
  4118. * these environment variables are in, so we sort both lists first. */
  4119. smartlist_add_all(env_vars_sorted, env_vars);
  4120. {
  4121. char **v;
  4122. for (v = env->unixoid_environment_block; *v; ++v) {
  4123. smartlist_add(env_vars_in_unixoid_env_block_sorted, *v);
  4124. }
  4125. }
  4126. smartlist_sort_strings(env_vars_sorted);
  4127. smartlist_sort_strings(env_vars_in_unixoid_env_block_sorted);
  4128. tt_want_int_op(smartlist_len(env_vars_sorted), OP_EQ,
  4129. smartlist_len(env_vars_in_unixoid_env_block_sorted));
  4130. {
  4131. int len = smartlist_len(env_vars_sorted);
  4132. int i;
  4133. if (smartlist_len(env_vars_in_unixoid_env_block_sorted) < len) {
  4134. len = smartlist_len(env_vars_in_unixoid_env_block_sorted);
  4135. }
  4136. for (i = 0; i < len; ++i) {
  4137. tt_want_str_op(smartlist_get(env_vars_sorted, i), OP_EQ,
  4138. smartlist_get(env_vars_in_unixoid_env_block_sorted, i));
  4139. }
  4140. }
  4141. /* Clean up. */
  4142. smartlist_free(env_vars_in_unixoid_env_block_sorted);
  4143. smartlist_free(env_vars_sorted);
  4144. SMARTLIST_FOREACH(env_vars, char *, x, tor_free(x));
  4145. smartlist_free(env_vars);
  4146. process_environment_free(env);
  4147. }
  4148. /** Test set_environment_variable_in_smartlist */
  4149. static void
  4150. test_util_set_env_var_in_sl(void *ptr)
  4151. {
  4152. /* The environment variables in these strings are in arbitrary
  4153. * order; we sort the resulting lists before comparing them.
  4154. *
  4155. * (They *will not* end up in the order shown in
  4156. * expected_resulting_env_vars_string.) */
  4157. const char *base_env_vars_string =
  4158. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  4159. "HOME=/home/foozer\n"
  4160. "TERM=xterm\n"
  4161. "SHELL=/bin/ksh\n"
  4162. "USER=foozer\n"
  4163. "LOGNAME=foozer\n"
  4164. "USERNAME=foozer\n"
  4165. "LANG=en_US.utf8\n"
  4166. ;
  4167. const char *new_env_vars_string =
  4168. "TERM=putty\n"
  4169. "DISPLAY=:18.0\n"
  4170. ;
  4171. const char *expected_resulting_env_vars_string =
  4172. "PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin\n"
  4173. "HOME=/home/foozer\n"
  4174. "TERM=putty\n"
  4175. "SHELL=/bin/ksh\n"
  4176. "USER=foozer\n"
  4177. "LOGNAME=foozer\n"
  4178. "USERNAME=foozer\n"
  4179. "LANG=en_US.utf8\n"
  4180. "DISPLAY=:18.0\n"
  4181. ;
  4182. smartlist_t *merged_env_vars =
  4183. smartlist_new_from_text_lines(base_env_vars_string);
  4184. smartlist_t *new_env_vars =
  4185. smartlist_new_from_text_lines(new_env_vars_string);
  4186. smartlist_t *expected_resulting_env_vars =
  4187. smartlist_new_from_text_lines(expected_resulting_env_vars_string);
  4188. /* Elements of merged_env_vars are heap-allocated, and must be
  4189. * freed. Some of them are (or should) be freed by
  4190. * set_environment_variable_in_smartlist.
  4191. *
  4192. * Elements of new_env_vars are heap-allocated, but are copied into
  4193. * merged_env_vars, so they are not freed separately at the end of
  4194. * the function.
  4195. *
  4196. * Elements of expected_resulting_env_vars are heap-allocated, and
  4197. * must be freed. */
  4198. (void)ptr;
  4199. SMARTLIST_FOREACH(new_env_vars, char *, env_var,
  4200. set_environment_variable_in_smartlist(merged_env_vars,
  4201. env_var,
  4202. tor_free_,
  4203. 1));
  4204. smartlist_sort_strings(merged_env_vars);
  4205. smartlist_sort_strings(expected_resulting_env_vars);
  4206. tt_want_int_op(smartlist_len(merged_env_vars), OP_EQ,
  4207. smartlist_len(expected_resulting_env_vars));
  4208. {
  4209. int len = smartlist_len(merged_env_vars);
  4210. int i;
  4211. if (smartlist_len(expected_resulting_env_vars) < len) {
  4212. len = smartlist_len(expected_resulting_env_vars);
  4213. }
  4214. for (i = 0; i < len; ++i) {
  4215. tt_want_str_op(smartlist_get(merged_env_vars, i), OP_EQ,
  4216. smartlist_get(expected_resulting_env_vars, i));
  4217. }
  4218. }
  4219. /* Clean up. */
  4220. SMARTLIST_FOREACH(merged_env_vars, char *, x, tor_free(x));
  4221. smartlist_free(merged_env_vars);
  4222. smartlist_free(new_env_vars);
  4223. SMARTLIST_FOREACH(expected_resulting_env_vars, char *, x, tor_free(x));
  4224. smartlist_free(expected_resulting_env_vars);
  4225. }
  4226. static void
  4227. test_util_weak_random(void *arg)
  4228. {
  4229. int i, j, n[16];
  4230. tor_weak_rng_t rng;
  4231. (void) arg;
  4232. tor_init_weak_random(&rng, (unsigned)time(NULL));
  4233. for (i = 1; i <= 256; ++i) {
  4234. for (j=0;j<100;++j) {
  4235. int r = tor_weak_random_range(&rng, i);
  4236. tt_int_op(0, OP_LE, r);
  4237. tt_int_op(r, OP_LT, i);
  4238. }
  4239. }
  4240. memset(n,0,sizeof(n));
  4241. for (j=0;j<8192;++j) {
  4242. n[tor_weak_random_range(&rng, 16)]++;
  4243. }
  4244. for (i=0;i<16;++i)
  4245. tt_int_op(n[i], OP_GT, 0);
  4246. done:
  4247. ;
  4248. }
  4249. static void
  4250. test_util_mathlog(void *arg)
  4251. {
  4252. double d;
  4253. (void) arg;
  4254. d = tor_mathlog(2.718281828);
  4255. tt_double_op(fabs(d - 1.0), OP_LT, .000001);
  4256. d = tor_mathlog(10);
  4257. tt_double_op(fabs(d - 2.30258509), OP_LT, .000001);
  4258. done:
  4259. ;
  4260. }
  4261. static void
  4262. test_util_fraction(void *arg)
  4263. {
  4264. uint64_t a,b;
  4265. (void)arg;
  4266. a = 99; b = 30;
  4267. simplify_fraction64(&a,&b);
  4268. tt_u64_op(a, OP_EQ, 33);
  4269. tt_u64_op(b, OP_EQ, 10);
  4270. a = 3000000; b = 10000000;
  4271. simplify_fraction64(&a,&b);
  4272. tt_u64_op(a, OP_EQ, 3);
  4273. tt_u64_op(b, OP_EQ, 10);
  4274. a = 0; b = 15;
  4275. simplify_fraction64(&a,&b);
  4276. tt_u64_op(a, OP_EQ, 0);
  4277. tt_u64_op(b, OP_EQ, 1);
  4278. done:
  4279. ;
  4280. }
  4281. static void
  4282. test_util_round_to_next_multiple_of(void *arg)
  4283. {
  4284. (void)arg;
  4285. tt_u64_op(round_uint64_to_next_multiple_of(0,1), OP_EQ, 0);
  4286. tt_u64_op(round_uint64_to_next_multiple_of(0,7), OP_EQ, 0);
  4287. tt_u64_op(round_uint64_to_next_multiple_of(99,1), OP_EQ, 99);
  4288. tt_u64_op(round_uint64_to_next_multiple_of(99,7), OP_EQ, 105);
  4289. tt_u64_op(round_uint64_to_next_multiple_of(99,9), OP_EQ, 99);
  4290. tt_u64_op(round_uint64_to_next_multiple_of(UINT64_MAX,2), OP_EQ,
  4291. UINT64_MAX);
  4292. tt_int_op(round_uint32_to_next_multiple_of(0,1), OP_EQ, 0);
  4293. tt_int_op(round_uint32_to_next_multiple_of(0,7), OP_EQ, 0);
  4294. tt_int_op(round_uint32_to_next_multiple_of(99,1), OP_EQ, 99);
  4295. tt_int_op(round_uint32_to_next_multiple_of(99,7), OP_EQ, 105);
  4296. tt_int_op(round_uint32_to_next_multiple_of(99,9), OP_EQ, 99);
  4297. tt_int_op(round_uint32_to_next_multiple_of(UINT32_MAX,2), OP_EQ,
  4298. UINT32_MAX);
  4299. tt_uint_op(round_to_next_multiple_of(0,1), OP_EQ, 0);
  4300. tt_uint_op(round_to_next_multiple_of(0,7), OP_EQ, 0);
  4301. tt_uint_op(round_to_next_multiple_of(99,1), OP_EQ, 99);
  4302. tt_uint_op(round_to_next_multiple_of(99,7), OP_EQ, 105);
  4303. tt_uint_op(round_to_next_multiple_of(99,9), OP_EQ, 99);
  4304. tt_uint_op(round_to_next_multiple_of(UINT_MAX,2), OP_EQ,
  4305. UINT_MAX);
  4306. done:
  4307. ;
  4308. }
  4309. static void
  4310. test_util_laplace(void *arg)
  4311. {
  4312. /* Sample values produced using Python's SciPy:
  4313. *
  4314. * >>> from scipy.stats import laplace
  4315. * >>> laplace.ppf([-0.01, 0.0, 0.01, 0.5, 0.51, 0.99, 1.0, 1.01],
  4316. ... loc = 24, scale = 24)
  4317. * array([ nan, -inf, -69.88855213, 24. ,
  4318. * 24.48486498, 117.88855213, inf, nan])
  4319. */
  4320. const double mu = 24.0, b = 24.0;
  4321. const double delta_f = 15.0, epsilon = 0.3; /* b = 15.0 / 0.3 = 50.0 */
  4322. (void)arg;
  4323. tt_i64_op(INT64_MIN, OP_EQ, sample_laplace_distribution(mu, b, 0.0));
  4324. tt_i64_op(-69, OP_EQ, sample_laplace_distribution(mu, b, 0.01));
  4325. tt_i64_op(24, OP_EQ, sample_laplace_distribution(mu, b, 0.5));
  4326. tt_i64_op(24, OP_EQ, sample_laplace_distribution(mu, b, 0.51));
  4327. tt_i64_op(117, OP_EQ, sample_laplace_distribution(mu, b, 0.99));
  4328. /* >>> laplace.ppf([0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 0.99],
  4329. * ... loc = 0, scale = 50)
  4330. * array([ -inf, -80.47189562, -34.65735903, 0. ,
  4331. * 34.65735903, 80.47189562, 195.60115027])
  4332. */
  4333. tt_i64_op(INT64_MIN + 20, OP_EQ,
  4334. add_laplace_noise(20, 0.0, delta_f, epsilon));
  4335. tt_i64_op(-60, OP_EQ, add_laplace_noise(20, 0.1, delta_f, epsilon));
  4336. tt_i64_op(-14, OP_EQ, add_laplace_noise(20, 0.25, delta_f, epsilon));
  4337. tt_i64_op(20, OP_EQ, add_laplace_noise(20, 0.5, delta_f, epsilon));
  4338. tt_i64_op(54, OP_EQ, add_laplace_noise(20, 0.75, delta_f, epsilon));
  4339. tt_i64_op(100, OP_EQ, add_laplace_noise(20, 0.9, delta_f, epsilon));
  4340. tt_i64_op(215, OP_EQ, add_laplace_noise(20, 0.99, delta_f, epsilon));
  4341. /* Test extreme values of signal with maximally negative values of noise
  4342. * 1.0000000000000002 is the smallest number > 1
  4343. * 0.0000000000000002 is the double epsilon (error when calculating near 1)
  4344. * this is approximately 1/(2^52)
  4345. * per https://en.wikipedia.org/wiki/Double_precision
  4346. * (let's not descend into the world of subnormals)
  4347. * >>> laplace.ppf([0, 0.0000000000000002], loc = 0, scale = 1)
  4348. * array([ -inf, -35.45506713])
  4349. */
  4350. const double noscale_df = 1.0, noscale_eps = 1.0;
  4351. tt_i64_op(INT64_MIN, OP_EQ,
  4352. add_laplace_noise(0, 0.0, noscale_df, noscale_eps));
  4353. /* is it clipped to INT64_MIN? */
  4354. tt_i64_op(INT64_MIN, OP_EQ,
  4355. add_laplace_noise(-1, 0.0, noscale_df, noscale_eps));
  4356. tt_i64_op(INT64_MIN, OP_EQ,
  4357. add_laplace_noise(INT64_MIN, 0.0,
  4358. noscale_df, noscale_eps));
  4359. /* ... even when scaled? */
  4360. tt_i64_op(INT64_MIN, OP_EQ,
  4361. add_laplace_noise(0, 0.0, delta_f, epsilon));
  4362. tt_i64_op(INT64_MIN, OP_EQ,
  4363. add_laplace_noise(0, 0.0,
  4364. DBL_MAX, 1));
  4365. tt_i64_op(INT64_MIN, OP_EQ,
  4366. add_laplace_noise(INT64_MIN, 0.0,
  4367. DBL_MAX, 1));
  4368. /* does it play nice with INT64_MAX? */
  4369. tt_i64_op((INT64_MIN + INT64_MAX), OP_EQ,
  4370. add_laplace_noise(INT64_MAX, 0.0,
  4371. noscale_df, noscale_eps));
  4372. /* do near-zero fractional values work? */
  4373. const double min_dbl_error = 0.0000000000000002;
  4374. tt_i64_op(-35, OP_EQ,
  4375. add_laplace_noise(0, min_dbl_error,
  4376. noscale_df, noscale_eps));
  4377. tt_i64_op(INT64_MIN, OP_EQ,
  4378. add_laplace_noise(INT64_MIN, min_dbl_error,
  4379. noscale_df, noscale_eps));
  4380. tt_i64_op((-35 + INT64_MAX), OP_EQ,
  4381. add_laplace_noise(INT64_MAX, min_dbl_error,
  4382. noscale_df, noscale_eps));
  4383. tt_i64_op(INT64_MIN, OP_EQ,
  4384. add_laplace_noise(0, min_dbl_error,
  4385. DBL_MAX, 1));
  4386. tt_i64_op((INT64_MAX + INT64_MIN), OP_EQ,
  4387. add_laplace_noise(INT64_MAX, min_dbl_error,
  4388. DBL_MAX, 1));
  4389. tt_i64_op(INT64_MIN, OP_EQ,
  4390. add_laplace_noise(INT64_MIN, min_dbl_error,
  4391. DBL_MAX, 1));
  4392. /* does it play nice with INT64_MAX? */
  4393. tt_i64_op((INT64_MAX - 35), OP_EQ,
  4394. add_laplace_noise(INT64_MAX, min_dbl_error,
  4395. noscale_df, noscale_eps));
  4396. /* Test extreme values of signal with maximally positive values of noise
  4397. * 1.0000000000000002 is the smallest number > 1
  4398. * 0.9999999999999998 is the greatest number < 1 by calculation
  4399. * per https://en.wikipedia.org/wiki/Double_precision
  4400. * >>> laplace.ppf([1.0, 0.9999999999999998], loc = 0, scale = 1)
  4401. * array([inf, 35.35050621])
  4402. * but the function rejects p == 1.0, so we just use max_dbl_lt_one
  4403. */
  4404. const double max_dbl_lt_one = 0.9999999999999998;
  4405. /* do near-one fractional values work? */
  4406. tt_i64_op(35, OP_EQ,
  4407. add_laplace_noise(0, max_dbl_lt_one, noscale_df, noscale_eps));
  4408. /* is it clipped to INT64_MAX? */
  4409. tt_i64_op(INT64_MAX, OP_EQ,
  4410. add_laplace_noise(INT64_MAX - 35, max_dbl_lt_one,
  4411. noscale_df, noscale_eps));
  4412. tt_i64_op(INT64_MAX, OP_EQ,
  4413. add_laplace_noise(INT64_MAX - 34, max_dbl_lt_one,
  4414. noscale_df, noscale_eps));
  4415. tt_i64_op(INT64_MAX, OP_EQ,
  4416. add_laplace_noise(INT64_MAX, max_dbl_lt_one,
  4417. noscale_df, noscale_eps));
  4418. /* ... even when scaled? */
  4419. tt_i64_op(INT64_MAX, OP_EQ,
  4420. add_laplace_noise(INT64_MAX, max_dbl_lt_one,
  4421. delta_f, epsilon));
  4422. tt_i64_op((INT64_MIN + INT64_MAX), OP_EQ,
  4423. add_laplace_noise(INT64_MIN, max_dbl_lt_one,
  4424. DBL_MAX, 1));
  4425. tt_i64_op(INT64_MAX, OP_EQ,
  4426. add_laplace_noise(INT64_MAX, max_dbl_lt_one,
  4427. DBL_MAX, 1));
  4428. /* does it play nice with INT64_MIN? */
  4429. tt_i64_op((INT64_MIN + 35), OP_EQ,
  4430. add_laplace_noise(INT64_MIN, max_dbl_lt_one,
  4431. noscale_df, noscale_eps));
  4432. done:
  4433. ;
  4434. }
  4435. static void
  4436. test_util_clamp_double_to_int64(void *arg)
  4437. {
  4438. (void)arg;
  4439. tt_i64_op(INT64_MIN, OP_EQ, clamp_double_to_int64(-INFINITY_DBL));
  4440. tt_i64_op(INT64_MIN, OP_EQ,
  4441. clamp_double_to_int64(-1.0 * pow(2.0, 64.0) - 1.0));
  4442. tt_i64_op(INT64_MIN, OP_EQ,
  4443. clamp_double_to_int64(-1.0 * pow(2.0, 63.0) - 1.0));
  4444. tt_i64_op(((uint64_t) -1) << 53, OP_EQ,
  4445. clamp_double_to_int64(-1.0 * pow(2.0, 53.0)));
  4446. tt_i64_op((((uint64_t) -1) << 53) + 1, OP_EQ,
  4447. clamp_double_to_int64(-1.0 * pow(2.0, 53.0) + 1.0));
  4448. tt_i64_op(-1, OP_EQ, clamp_double_to_int64(-1.0));
  4449. tt_i64_op(0, OP_EQ, clamp_double_to_int64(-0.9));
  4450. tt_i64_op(0, OP_EQ, clamp_double_to_int64(-0.1));
  4451. tt_i64_op(0, OP_EQ, clamp_double_to_int64(0.0));
  4452. tt_i64_op(0, OP_EQ, clamp_double_to_int64(NAN_DBL));
  4453. tt_i64_op(0, OP_EQ, clamp_double_to_int64(0.1));
  4454. tt_i64_op(0, OP_EQ, clamp_double_to_int64(0.9));
  4455. tt_i64_op(1, OP_EQ, clamp_double_to_int64(1.0));
  4456. tt_i64_op((((int64_t) 1) << 53) - 1, OP_EQ,
  4457. clamp_double_to_int64(pow(2.0, 53.0) - 1.0));
  4458. tt_i64_op(((int64_t) 1) << 53, OP_EQ,
  4459. clamp_double_to_int64(pow(2.0, 53.0)));
  4460. tt_i64_op(INT64_MAX, OP_EQ,
  4461. clamp_double_to_int64(pow(2.0, 63.0)));
  4462. tt_i64_op(INT64_MAX, OP_EQ,
  4463. clamp_double_to_int64(pow(2.0, 64.0)));
  4464. tt_i64_op(INT64_MAX, OP_EQ, clamp_double_to_int64(INFINITY_DBL));
  4465. done:
  4466. ;
  4467. }
  4468. #ifdef FD_CLOEXEC
  4469. #define CAN_CHECK_CLOEXEC
  4470. static int
  4471. fd_is_cloexec(tor_socket_t fd)
  4472. {
  4473. int flags = fcntl(fd, F_GETFD, 0);
  4474. return (flags & FD_CLOEXEC) == FD_CLOEXEC;
  4475. }
  4476. #endif /* defined(FD_CLOEXEC) */
  4477. #ifndef _WIN32
  4478. #define CAN_CHECK_NONBLOCK
  4479. static int
  4480. fd_is_nonblocking(tor_socket_t fd)
  4481. {
  4482. int flags = fcntl(fd, F_GETFL, 0);
  4483. return (flags & O_NONBLOCK) == O_NONBLOCK;
  4484. }
  4485. #endif /* !defined(_WIN32) */
  4486. #define ERRNO_IS_EPROTO(e) (e == SOCK_ERRNO(EPROTONOSUPPORT))
  4487. #define SOCK_ERR_IS_EPROTO(s) ERRNO_IS_EPROTO(tor_socket_errno(s))
  4488. /* Test for tor_open_socket*, using IPv4 or IPv6 depending on arg. */
  4489. static void
  4490. test_util_socket(void *arg)
  4491. {
  4492. const int domain = !strcmp(arg, "4") ? AF_INET : AF_INET6;
  4493. tor_socket_t fd1 = TOR_INVALID_SOCKET;
  4494. tor_socket_t fd2 = TOR_INVALID_SOCKET;
  4495. tor_socket_t fd3 = TOR_INVALID_SOCKET;
  4496. tor_socket_t fd4 = TOR_INVALID_SOCKET;
  4497. int n = get_n_open_sockets();
  4498. TT_BLATHER(("Starting with %d open sockets.", n));
  4499. (void)arg;
  4500. fd1 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 0, 0);
  4501. int err = tor_socket_errno(fd1);
  4502. if (fd1 < 0 && (err == SOCK_ERRNO(EPROTONOSUPPORT) ||
  4503. err == SOCK_ERRNO(EAFNOSUPPORT))) {
  4504. /* Assume we're on an IPv4-only or IPv6-only system, and give up now. */
  4505. goto done;
  4506. }
  4507. fd2 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 0, 1);
  4508. tt_assert(SOCKET_OK(fd1));
  4509. tt_assert(SOCKET_OK(fd2));
  4510. tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
  4511. //fd3 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 0);
  4512. //fd4 = tor_open_socket_with_extensions(domain, SOCK_STREAM, 0, 1, 1);
  4513. fd3 = tor_open_socket(domain, SOCK_STREAM, 0);
  4514. fd4 = tor_open_socket_nonblocking(domain, SOCK_STREAM, 0);
  4515. tt_assert(SOCKET_OK(fd3));
  4516. tt_assert(SOCKET_OK(fd4));
  4517. tt_int_op(get_n_open_sockets(), OP_EQ, n + 4);
  4518. #ifdef CAN_CHECK_CLOEXEC
  4519. tt_int_op(fd_is_cloexec(fd1), OP_EQ, 0);
  4520. tt_int_op(fd_is_cloexec(fd2), OP_EQ, 0);
  4521. tt_int_op(fd_is_cloexec(fd3), OP_EQ, 1);
  4522. tt_int_op(fd_is_cloexec(fd4), OP_EQ, 1);
  4523. #endif /* defined(CAN_CHECK_CLOEXEC) */
  4524. #ifdef CAN_CHECK_NONBLOCK
  4525. tt_int_op(fd_is_nonblocking(fd1), OP_EQ, 0);
  4526. tt_int_op(fd_is_nonblocking(fd2), OP_EQ, 1);
  4527. tt_int_op(fd_is_nonblocking(fd3), OP_EQ, 0);
  4528. tt_int_op(fd_is_nonblocking(fd4), OP_EQ, 1);
  4529. #endif /* defined(CAN_CHECK_NONBLOCK) */
  4530. tor_assert(tor_close_socket == tor_close_socket__real);
  4531. /* we use close_socket__real here so that coverity can tell that we are
  4532. * really closing these sockets. */
  4533. tor_close_socket__real(fd1);
  4534. tor_close_socket__real(fd2);
  4535. fd1 = fd2 = TOR_INVALID_SOCKET;
  4536. tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
  4537. tor_close_socket__real(fd3);
  4538. tor_close_socket__real(fd4);
  4539. fd3 = fd4 = TOR_INVALID_SOCKET;
  4540. tt_int_op(get_n_open_sockets(), OP_EQ, n);
  4541. done:
  4542. if (SOCKET_OK(fd1))
  4543. tor_close_socket__real(fd1);
  4544. if (SOCKET_OK(fd2))
  4545. tor_close_socket__real(fd2);
  4546. if (SOCKET_OK(fd3))
  4547. tor_close_socket__real(fd3);
  4548. if (SOCKET_OK(fd4))
  4549. tor_close_socket__real(fd4);
  4550. }
  4551. #if 0
  4552. static int
  4553. is_there_a_localhost(int family)
  4554. {
  4555. tor_socket_t s;
  4556. s = tor_open_socket(family, SOCK_STREAM, IPPROTO_TCP);
  4557. tor_assert(SOCKET_OK(s));
  4558. int result = 0;
  4559. if (family == AF_INET) {
  4560. struct sockaddr_in s_in;
  4561. memset(&s_in, 0, sizeof(s_in));
  4562. s_in.sin_family = AF_INET;
  4563. s_in.sin_addr.s_addr = htonl(0x7f000001);
  4564. s_in.sin_port = 0;
  4565. if (bind(s, (void*)&s_in, sizeof(s_in)) == 0) {
  4566. result = 1;
  4567. }
  4568. } else if (family == AF_INET6) {
  4569. struct sockaddr_in6 sin6;
  4570. memset(&sin6, 0, sizeof(sin6));
  4571. sin6.sin6_family = AF_INET6;
  4572. sin6.sin6_addr.s6_addr[15] = 1;
  4573. sin6.sin6_port = 0;
  4574. }
  4575. tor_close_socket(s);
  4576. return result;
  4577. }
  4578. #endif /* 0 */
  4579. /* Test for socketpair and ersatz_socketpair(). We test them both, since
  4580. * the latter is a tolerably good way to exercise tor_accept_socket(). */
  4581. static void
  4582. test_util_socketpair(void *arg)
  4583. {
  4584. const int ersatz = !strcmp(arg, "1");
  4585. int (*const tor_socketpair_fn)(int, int, int, tor_socket_t[2]) =
  4586. ersatz ? tor_ersatz_socketpair : tor_socketpair;
  4587. int n = get_n_open_sockets();
  4588. tor_socket_t fds[2] = {TOR_INVALID_SOCKET, TOR_INVALID_SOCKET};
  4589. const int family = AF_UNIX;
  4590. int socketpair_result = 0;
  4591. socketpair_result = tor_socketpair_fn(family, SOCK_STREAM, 0, fds);
  4592. #ifdef __FreeBSD__
  4593. /* If there is no 127.0.0.1, tor_ersatz_socketpair will and must fail.
  4594. * Otherwise, we risk exposing a socketpair on a routable IP address. (Some
  4595. * BSD jails use a routable address for localhost. Fortunately, they have
  4596. * the real AF_UNIX socketpair.) */
  4597. if (ersatz && socketpair_result < 0) {
  4598. /* In my testing, an IPv6-only FreeBSD jail without ::1 returned EINVAL.
  4599. * Assume we're on a machine without 127.0.0.1 or ::1 and give up now. */
  4600. tt_skip();
  4601. }
  4602. #endif /* defined(__FreeBSD__) */
  4603. #ifdef ENETUNREACH
  4604. if (ersatz && socketpair_result == -ENETUNREACH) {
  4605. /* We can also fail with -ENETUNREACH if we have no network stack at
  4606. * all. */
  4607. tt_skip();
  4608. }
  4609. #endif /* defined(ENETUNREACH) */
  4610. tt_int_op(0, OP_EQ, socketpair_result);
  4611. tt_assert(SOCKET_OK(fds[0]));
  4612. tt_assert(SOCKET_OK(fds[1]));
  4613. if (ersatz)
  4614. tt_int_op(get_n_open_sockets(), OP_EQ, n);
  4615. else
  4616. tt_int_op(get_n_open_sockets(), OP_EQ, n + 2);
  4617. #ifdef CAN_CHECK_CLOEXEC
  4618. tt_int_op(fd_is_cloexec(fds[0]), OP_EQ, !ersatz);
  4619. tt_int_op(fd_is_cloexec(fds[1]), OP_EQ, !ersatz);
  4620. #endif
  4621. #ifdef CAN_CHECK_NONBLOCK
  4622. tt_int_op(fd_is_nonblocking(fds[0]), OP_EQ, 0);
  4623. tt_int_op(fd_is_nonblocking(fds[1]), OP_EQ, 0);
  4624. #endif
  4625. done:
  4626. if (ersatz) {
  4627. if (SOCKET_OK(fds[0]))
  4628. tor_close_socket_simple(fds[0]);
  4629. if (SOCKET_OK(fds[1]))
  4630. tor_close_socket_simple(fds[1]);
  4631. } else {
  4632. if (SOCKET_OK(fds[0]))
  4633. tor_close_socket(fds[0]);
  4634. if (SOCKET_OK(fds[1]))
  4635. tor_close_socket(fds[1]);
  4636. }
  4637. }
  4638. #undef SOCKET_EPROTO
  4639. static void
  4640. test_util_max_mem(void *arg)
  4641. {
  4642. size_t memory1, memory2;
  4643. int r, r2;
  4644. (void) arg;
  4645. r = get_total_system_memory(&memory1);
  4646. r2 = get_total_system_memory(&memory2);
  4647. tt_int_op(r, OP_EQ, r2);
  4648. tt_uint_op(memory2, OP_EQ, memory1);
  4649. TT_BLATHER(("System memory: %"TOR_PRIuSZ, (memory1)));
  4650. if (r==0) {
  4651. /* You have at least a megabyte. */
  4652. tt_uint_op(memory1, OP_GT, (1<<20));
  4653. } else {
  4654. /* You do not have a petabyte. */
  4655. #if SIZEOF_SIZE_T >= 8
  4656. tt_u64_op(memory1, OP_LT, (UINT64_C(1)<<50));
  4657. #endif
  4658. }
  4659. done:
  4660. ;
  4661. }
  4662. static void
  4663. test_util_dest_validation_edgecase(void *arg)
  4664. {
  4665. (void)arg;
  4666. tt_assert(!string_is_valid_dest(NULL));
  4667. tt_assert(!string_is_valid_dest(""));
  4668. done:
  4669. return;
  4670. }
  4671. static void
  4672. test_util_hostname_validation(void *arg)
  4673. {
  4674. (void)arg;
  4675. // Lets try valid hostnames first.
  4676. tt_assert(string_is_valid_nonrfc_hostname("torproject.org"));
  4677. tt_assert(string_is_valid_nonrfc_hostname("ocw.mit.edu"));
  4678. tt_assert(string_is_valid_nonrfc_hostname("i.4cdn.org"));
  4679. tt_assert(string_is_valid_nonrfc_hostname("stanford.edu"));
  4680. tt_assert(string_is_valid_nonrfc_hostname("multiple-words-with-hypens.jp"));
  4681. // Subdomain name cannot start with '-' or '_'.
  4682. tt_assert(!string_is_valid_nonrfc_hostname("-torproject.org"));
  4683. tt_assert(!string_is_valid_nonrfc_hostname("subdomain.-domain.org"));
  4684. tt_assert(!string_is_valid_nonrfc_hostname("-subdomain.domain.org"));
  4685. tt_assert(!string_is_valid_nonrfc_hostname("___abc.org"));
  4686. // Hostnames cannot contain non-alphanumeric characters.
  4687. tt_assert(!string_is_valid_nonrfc_hostname("%%domain.\\org."));
  4688. tt_assert(!string_is_valid_nonrfc_hostname("***x.net"));
  4689. tt_assert(!string_is_valid_nonrfc_hostname("\xff\xffxyz.org"));
  4690. tt_assert(!string_is_valid_nonrfc_hostname("word1 word2.net"));
  4691. // Test workaround for nytimes.com stupidity, technically invalid,
  4692. // but we allow it since they are big, even though they are failing to
  4693. // comply with a ~30 year old standard.
  4694. tt_assert(string_is_valid_nonrfc_hostname("core3_euw1.fabrik.nytimes.com"));
  4695. // Firefox passes FQDNs with trailing '.'s directly to the SOCKS proxy,
  4696. // which is redundant since the spec states DOMAINNAME addresses are fully
  4697. // qualified. While unusual, this should be tollerated.
  4698. tt_assert(string_is_valid_nonrfc_hostname("core9_euw1.fabrik.nytimes.com."));
  4699. tt_assert(!string_is_valid_nonrfc_hostname(
  4700. "..washingtonpost.is.better.com"));
  4701. tt_assert(!string_is_valid_nonrfc_hostname("so.is..ft.com"));
  4702. tt_assert(!string_is_valid_nonrfc_hostname("..."));
  4703. // XXX: do we allow single-label DNS names?
  4704. // We shouldn't for SOCKS (spec says "contains a fully-qualified domain name"
  4705. // but only test pathologically malformed traling '.' cases for now.
  4706. tt_assert(!string_is_valid_nonrfc_hostname("."));
  4707. tt_assert(!string_is_valid_nonrfc_hostname(".."));
  4708. // IP address strings are not hostnames.
  4709. tt_assert(!string_is_valid_nonrfc_hostname("8.8.8.8"));
  4710. tt_assert(!string_is_valid_nonrfc_hostname("[2a00:1450:401b:800::200e]"));
  4711. tt_assert(!string_is_valid_nonrfc_hostname("2a00:1450:401b:800::200e"));
  4712. // We allow alphanumeric TLDs. For discussion, see ticket #25055.
  4713. tt_assert(string_is_valid_nonrfc_hostname("lucky.13"));
  4714. tt_assert(string_is_valid_nonrfc_hostname("luck.y13"));
  4715. tt_assert(string_is_valid_nonrfc_hostname("luck.y13."));
  4716. // We allow punycode TLDs. For examples, see
  4717. // http://data.iana.org/TLD/tlds-alpha-by-domain.txt
  4718. tt_assert(string_is_valid_nonrfc_hostname("example.xn--l1acc"));
  4719. done:
  4720. return;
  4721. }
  4722. static void
  4723. test_util_ipv4_validation(void *arg)
  4724. {
  4725. (void)arg;
  4726. tt_assert(string_is_valid_ipv4_address("192.168.0.1"));
  4727. tt_assert(string_is_valid_ipv4_address("8.8.8.8"));
  4728. tt_assert(!string_is_valid_ipv4_address("abcd"));
  4729. tt_assert(!string_is_valid_ipv4_address("300.300.300.300"));
  4730. tt_assert(!string_is_valid_ipv4_address("8.8."));
  4731. done:
  4732. return;
  4733. }
  4734. static void
  4735. test_util_ipv6_validation(void *arg)
  4736. {
  4737. (void)arg;
  4738. tt_assert(string_is_valid_ipv6_address("2a00:1450:401b:800::200e"));
  4739. tt_assert(!string_is_valid_ipv6_address("11:22::33:44:"));
  4740. done:
  4741. return;
  4742. }
  4743. static void
  4744. test_util_writepid(void *arg)
  4745. {
  4746. (void) arg;
  4747. char *contents = NULL;
  4748. const char *fname = get_fname("tmp_pid");
  4749. unsigned long pid;
  4750. char c;
  4751. write_pidfile(fname);
  4752. contents = read_file_to_str(fname, 0, NULL);
  4753. tt_assert(contents);
  4754. int n = tor_sscanf(contents, "%lu\n%c", &pid, &c);
  4755. tt_int_op(n, OP_EQ, 1);
  4756. #ifdef _WIN32
  4757. tt_uint_op(pid, OP_EQ, _getpid());
  4758. #else
  4759. tt_uint_op(pid, OP_EQ, getpid());
  4760. #endif
  4761. done:
  4762. tor_free(contents);
  4763. }
  4764. static void
  4765. test_util_get_avail_disk_space(void *arg)
  4766. {
  4767. (void) arg;
  4768. int64_t val;
  4769. /* No answer for nonexistent directory */
  4770. val = tor_get_avail_disk_space("/akljasdfklsajdklasjkldjsa");
  4771. tt_i64_op(val, OP_EQ, -1);
  4772. /* Try the current directory */
  4773. val = tor_get_avail_disk_space(".");
  4774. #if !defined(HAVE_STATVFS) && !defined(_WIN32)
  4775. tt_i64_op(val, OP_EQ, -1); /* You don't have an implementation for this */
  4776. #else
  4777. tt_i64_op(val, OP_GT, 0); /* You have some space. */
  4778. tt_i64_op(val, OP_LT, ((int64_t)1)<<56); /* You don't have a zebibyte */
  4779. #endif /* !defined(HAVE_STATVFS) && !defined(_WIN32) */
  4780. done:
  4781. ;
  4782. }
  4783. static void
  4784. test_util_touch_file(void *arg)
  4785. {
  4786. (void) arg;
  4787. const char *fname = get_fname("touch");
  4788. const time_t now = time(NULL);
  4789. struct stat st;
  4790. write_bytes_to_file(fname, "abc", 3, 1);
  4791. tt_int_op(0, OP_EQ, stat(fname, &st));
  4792. /* A subtle point: the filesystem time is not necessarily equal to the
  4793. * system clock time, since one can be using a monotonic clock, or coarse
  4794. * monotonic clock, or whatever. So we might wind up with an mtime a few
  4795. * microseconds ago. Let's just give it a lot of wiggle room. */
  4796. tt_i64_op(st.st_mtime, OP_GE, now - 1);
  4797. const time_t five_sec_ago = now - 5;
  4798. struct utimbuf u = { five_sec_ago, five_sec_ago };
  4799. tt_int_op(0, OP_EQ, utime(fname, &u));
  4800. tt_int_op(0, OP_EQ, stat(fname, &st));
  4801. /* Let's hope that utime/stat give the same second as a round-trip? */
  4802. tt_i64_op(st.st_mtime, OP_EQ, five_sec_ago);
  4803. /* Finally we can touch the file */
  4804. tt_int_op(0, OP_EQ, touch_file(fname));
  4805. tt_int_op(0, OP_EQ, stat(fname, &st));
  4806. tt_i64_op(st.st_mtime, OP_GE, now-1);
  4807. done:
  4808. ;
  4809. }
  4810. #ifndef _WIN32
  4811. static void
  4812. test_util_pwdb(void *arg)
  4813. {
  4814. (void) arg;
  4815. const struct passwd *me = NULL, *me2, *me3;
  4816. char *name = NULL;
  4817. char *dir = NULL;
  4818. /* Uncached case. */
  4819. /* Let's assume that we exist. */
  4820. me = tor_getpwuid(getuid());
  4821. tt_ptr_op(me, OP_NE, NULL);
  4822. name = tor_strdup(me->pw_name);
  4823. /* Uncached case */
  4824. me2 = tor_getpwnam(name);
  4825. tt_ptr_op(me2, OP_NE, NULL);
  4826. tt_int_op(me2->pw_uid, OP_EQ, getuid());
  4827. /* Cached case */
  4828. me3 = tor_getpwuid(getuid());
  4829. tt_ptr_op(me3, OP_NE, NULL);
  4830. tt_str_op(me3->pw_name, OP_EQ, name);
  4831. me3 = tor_getpwnam(name);
  4832. tt_ptr_op(me3, OP_NE, NULL);
  4833. tt_int_op(me3->pw_uid, OP_EQ, getuid());
  4834. dir = get_user_homedir(name);
  4835. tt_ptr_op(dir, OP_NE, NULL);
  4836. /* Try failing cases. First find a user that doesn't exist by name */
  4837. char randbytes[4];
  4838. char badname[9];
  4839. int i, found=0;
  4840. for (i = 0; i < 100; ++i) {
  4841. crypto_rand(randbytes, sizeof(randbytes));
  4842. base16_encode(badname, sizeof(badname), randbytes, sizeof(randbytes));
  4843. if (tor_getpwnam(badname) == NULL) {
  4844. found = 1;
  4845. break;
  4846. }
  4847. }
  4848. tt_assert(found);
  4849. tor_free(dir);
  4850. /* We should do a LOG_ERR */
  4851. setup_full_capture_of_logs(LOG_ERR);
  4852. dir = get_user_homedir(badname);
  4853. tt_ptr_op(dir, OP_EQ, NULL);
  4854. expect_log_msg_containing("not found");
  4855. tt_int_op(smartlist_len(mock_saved_logs()), OP_EQ, 1);
  4856. teardown_capture_of_logs();
  4857. /* Now try to find a user that doesn't exist by ID. */
  4858. found = 0;
  4859. for (i = 0; i < 1000; ++i) {
  4860. uid_t u;
  4861. crypto_rand((char*)&u, sizeof(u));
  4862. if (tor_getpwuid(u) == NULL) {
  4863. found = 1;
  4864. break;
  4865. }
  4866. }
  4867. tt_assert(found);
  4868. done:
  4869. tor_free(name);
  4870. tor_free(dir);
  4871. teardown_capture_of_logs();
  4872. }
  4873. #endif /* !defined(_WIN32) */
  4874. static void
  4875. test_util_calloc_check(void *arg)
  4876. {
  4877. (void) arg;
  4878. /* Easy cases that are good. */
  4879. tt_assert(size_mul_check(0,0));
  4880. tt_assert(size_mul_check(0,100));
  4881. tt_assert(size_mul_check(100,0));
  4882. tt_assert(size_mul_check(100,100));
  4883. /* Harder cases that are still good. */
  4884. tt_assert(size_mul_check(SIZE_MAX, 1));
  4885. tt_assert(size_mul_check(1, SIZE_MAX));
  4886. tt_assert(size_mul_check(SIZE_MAX / 10, 9));
  4887. tt_assert(size_mul_check(11, SIZE_MAX / 12));
  4888. const size_t sqrt_size_max_p1 = ((size_t)1) << (sizeof(size_t) * 4);
  4889. tt_assert(size_mul_check(sqrt_size_max_p1, sqrt_size_max_p1 - 1));
  4890. /* Cases that overflow */
  4891. tt_assert(! size_mul_check(SIZE_MAX, 2));
  4892. tt_assert(! size_mul_check(2, SIZE_MAX));
  4893. tt_assert(! size_mul_check(SIZE_MAX / 10, 11));
  4894. tt_assert(! size_mul_check(11, SIZE_MAX / 10));
  4895. tt_assert(! size_mul_check(SIZE_MAX / 8, 9));
  4896. tt_assert(! size_mul_check(sqrt_size_max_p1, sqrt_size_max_p1));
  4897. done:
  4898. ;
  4899. }
  4900. static void
  4901. test_util_monotonic_time(void *arg)
  4902. {
  4903. (void)arg;
  4904. monotime_t mt1, mt2;
  4905. monotime_coarse_t mtc1, mtc2;
  4906. uint64_t nsec1, nsec2, usec1, msec1;
  4907. uint64_t nsecc1, nsecc2, usecc1, msecc1;
  4908. uint32_t stamp1, stamp2;
  4909. monotime_init();
  4910. monotime_get(&mt1);
  4911. monotime_coarse_get(&mtc1);
  4912. nsec1 = monotime_absolute_nsec();
  4913. usec1 = monotime_absolute_usec();
  4914. msec1 = monotime_absolute_msec();
  4915. nsecc1 = monotime_coarse_absolute_nsec();
  4916. usecc1 = monotime_coarse_absolute_usec();
  4917. msecc1 = monotime_coarse_absolute_msec();
  4918. stamp1 = monotime_coarse_to_stamp(&mtc1);
  4919. tor_sleep_msec(200);
  4920. monotime_get(&mt2);
  4921. monotime_coarse_get(&mtc2);
  4922. nsec2 = monotime_absolute_nsec();
  4923. nsecc2 = monotime_coarse_absolute_nsec();
  4924. stamp2 = monotime_coarse_to_stamp(&mtc2);
  4925. /* We need to be a little careful here since we don't know the system load.
  4926. */
  4927. tt_i64_op(monotime_diff_msec(&mt1, &mt2), OP_GE, 175);
  4928. tt_i64_op(monotime_diff_msec(&mt1, &mt2), OP_LT, 1000);
  4929. tt_i64_op(monotime_coarse_diff_msec(&mtc1, &mtc2), OP_GE, 125);
  4930. tt_i64_op(monotime_coarse_diff_msec(&mtc1, &mtc2), OP_LT, 1000);
  4931. tt_u64_op(nsec2-nsec1, OP_GE, 175000000);
  4932. tt_u64_op(nsec2-nsec1, OP_LT, 1000000000);
  4933. tt_u64_op(nsecc2-nsecc1, OP_GE, 125000000);
  4934. tt_u64_op(nsecc2-nsecc1, OP_LT, 1000000000);
  4935. tt_u64_op(msec1, OP_GE, nsec1 / 1000000);
  4936. tt_u64_op(usec1, OP_GE, nsec1 / 1000);
  4937. tt_u64_op(msecc1, OP_GE, nsecc1 / 1000000);
  4938. tt_u64_op(usecc1, OP_GE, nsecc1 / 1000);
  4939. tt_u64_op(msec1, OP_LE, nsec1 / 1000000 + 10);
  4940. tt_u64_op(usec1, OP_LE, nsec1 / 1000 + 10000);
  4941. tt_u64_op(msecc1, OP_LE, nsecc1 / 1000000 + 10);
  4942. tt_u64_op(usecc1, OP_LE, nsecc1 / 1000 + 10000);
  4943. uint64_t coarse_stamp_diff =
  4944. monotime_coarse_stamp_units_to_approx_msec(stamp2-stamp1);
  4945. tt_u64_op(coarse_stamp_diff, OP_GE, 120);
  4946. tt_u64_op(coarse_stamp_diff, OP_LE, 1200);
  4947. {
  4948. uint64_t units = monotime_msec_to_approx_coarse_stamp_units(5000);
  4949. uint64_t ms = monotime_coarse_stamp_units_to_approx_msec(units);
  4950. tt_u64_op(ms, OP_GE, 4950);
  4951. tt_u64_op(ms, OP_LT, 5050);
  4952. }
  4953. done:
  4954. ;
  4955. }
  4956. static void
  4957. test_util_monotonic_time_ratchet(void *arg)
  4958. {
  4959. (void)arg;
  4960. monotime_init();
  4961. monotime_reset_ratchets_for_testing();
  4962. /* win32, performance counter ratchet. */
  4963. tt_i64_op(100, OP_EQ, ratchet_performance_counter(100));
  4964. tt_i64_op(101, OP_EQ, ratchet_performance_counter(101));
  4965. tt_i64_op(2000, OP_EQ, ratchet_performance_counter(2000));
  4966. tt_i64_op(2000, OP_EQ, ratchet_performance_counter(100));
  4967. tt_i64_op(2005, OP_EQ, ratchet_performance_counter(105));
  4968. tt_i64_op(3005, OP_EQ, ratchet_performance_counter(1105));
  4969. tt_i64_op(3005, OP_EQ, ratchet_performance_counter(1000));
  4970. tt_i64_op(3010, OP_EQ, ratchet_performance_counter(1005));
  4971. /* win32, GetTickCounts32 ratchet-and-rollover-detector. */
  4972. const int64_t R = ((int64_t)1) << 32;
  4973. tt_i64_op(5, OP_EQ, ratchet_coarse_performance_counter(5));
  4974. tt_i64_op(1000, OP_EQ, ratchet_coarse_performance_counter(1000));
  4975. tt_i64_op(5+R, OP_EQ, ratchet_coarse_performance_counter(5));
  4976. tt_i64_op(10+R, OP_EQ, ratchet_coarse_performance_counter(10));
  4977. tt_i64_op(4+R*2, OP_EQ, ratchet_coarse_performance_counter(4));
  4978. /* gettimeofday regular ratchet. */
  4979. struct timeval tv_in = {0,0}, tv_out;
  4980. tv_in.tv_usec = 9000;
  4981. ratchet_timeval(&tv_in, &tv_out);
  4982. tt_int_op(tv_out.tv_usec, OP_EQ, 9000);
  4983. tt_i64_op(tv_out.tv_sec, OP_EQ, 0);
  4984. tv_in.tv_sec = 1337;
  4985. tv_in.tv_usec = 0;
  4986. ratchet_timeval(&tv_in, &tv_out);
  4987. tt_int_op(tv_out.tv_usec, OP_EQ, 0);
  4988. tt_i64_op(tv_out.tv_sec, OP_EQ, 1337);
  4989. tv_in.tv_sec = 1336;
  4990. tv_in.tv_usec = 500000;
  4991. ratchet_timeval(&tv_in, &tv_out);
  4992. tt_int_op(tv_out.tv_usec, OP_EQ, 0);
  4993. tt_i64_op(tv_out.tv_sec, OP_EQ, 1337);
  4994. tv_in.tv_sec = 1337;
  4995. tv_in.tv_usec = 0;
  4996. ratchet_timeval(&tv_in, &tv_out);
  4997. tt_int_op(tv_out.tv_usec, OP_EQ, 500000);
  4998. tt_i64_op(tv_out.tv_sec, OP_EQ, 1337);
  4999. tv_in.tv_sec = 1337;
  5000. tv_in.tv_usec = 600000;
  5001. ratchet_timeval(&tv_in, &tv_out);
  5002. tt_int_op(tv_out.tv_usec, OP_EQ, 100000);
  5003. tt_i64_op(tv_out.tv_sec, OP_EQ, 1338);
  5004. tv_in.tv_sec = 1000;
  5005. tv_in.tv_usec = 1000;
  5006. ratchet_timeval(&tv_in, &tv_out);
  5007. tt_int_op(tv_out.tv_usec, OP_EQ, 100000);
  5008. tt_i64_op(tv_out.tv_sec, OP_EQ, 1338);
  5009. tv_in.tv_sec = 2000;
  5010. tv_in.tv_usec = 2000;
  5011. ratchet_timeval(&tv_in, &tv_out);
  5012. tt_int_op(tv_out.tv_usec, OP_EQ, 101000);
  5013. tt_i64_op(tv_out.tv_sec, OP_EQ, 2338);
  5014. done:
  5015. ;
  5016. }
  5017. static void
  5018. test_util_monotonic_time_zero(void *arg)
  5019. {
  5020. (void) arg;
  5021. monotime_t t1;
  5022. monotime_coarse_t ct1;
  5023. monotime_init();
  5024. /* Check 1: The current time is not zero. */
  5025. monotime_get(&t1);
  5026. monotime_coarse_get(&ct1);
  5027. tt_assert(!monotime_is_zero(&t1));
  5028. tt_assert(!monotime_coarse_is_zero(&ct1));
  5029. /* Check 2: The _zero() makes the time zero. */
  5030. monotime_zero(&t1);
  5031. monotime_coarse_zero(&ct1);
  5032. tt_assert(monotime_is_zero(&t1));
  5033. tt_assert(monotime_coarse_is_zero(&ct1));
  5034. done:
  5035. ;
  5036. }
  5037. static void
  5038. test_util_monotonic_time_add_msec(void *arg)
  5039. {
  5040. (void) arg;
  5041. monotime_t t1, t2;
  5042. monotime_coarse_t ct1, ct2;
  5043. monotime_init();
  5044. monotime_get(&t1);
  5045. monotime_coarse_get(&ct1);
  5046. /* adding zero does nothing */
  5047. monotime_add_msec(&t2, &t1, 0);
  5048. monotime_coarse_add_msec(&ct2, &ct1, 0);
  5049. tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 0);
  5050. tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 0);
  5051. /* Add 1337 msec; see if the diff function agree */
  5052. monotime_add_msec(&t2, &t1, 1337);
  5053. monotime_coarse_add_msec(&ct2, &ct1, 1337);
  5054. tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 1337);
  5055. tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 1337);
  5056. // The 32-bit variant must be within 1% of the regular one.
  5057. tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_GT, 1323);
  5058. tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_LT, 1350);
  5059. /* Add 1337 msec twice more; make sure that any second rollover issues
  5060. * worked. */
  5061. monotime_add_msec(&t2, &t2, 1337);
  5062. monotime_coarse_add_msec(&ct2, &ct2, 1337);
  5063. monotime_add_msec(&t2, &t2, 1337);
  5064. monotime_coarse_add_msec(&ct2, &ct2, 1337);
  5065. tt_i64_op(monotime_diff_msec(&t1, &t2), OP_EQ, 1337*3);
  5066. tt_i64_op(monotime_coarse_diff_msec(&ct1, &ct2), OP_EQ, 1337*3);
  5067. tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_GT, 3970);
  5068. tt_int_op(monotime_coarse_diff_msec32_(&ct1, &ct2), OP_LT, 4051);
  5069. done:
  5070. ;
  5071. }
  5072. static void
  5073. test_util_nowrap_math(void *arg)
  5074. {
  5075. (void)arg;
  5076. tt_u64_op(0, OP_EQ, tor_add_u32_nowrap(0, 0));
  5077. tt_u64_op(1, OP_EQ, tor_add_u32_nowrap(0, 1));
  5078. tt_u64_op(1, OP_EQ, tor_add_u32_nowrap(1, 0));
  5079. tt_u64_op(4, OP_EQ, tor_add_u32_nowrap(2, 2));
  5080. tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(UINT32_MAX-1, 2));
  5081. tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(2, UINT32_MAX-1));
  5082. tt_u64_op(UINT32_MAX, OP_EQ, tor_add_u32_nowrap(UINT32_MAX, UINT32_MAX));
  5083. done:
  5084. ;
  5085. }
  5086. static void
  5087. test_util_htonll(void *arg)
  5088. {
  5089. (void)arg;
  5090. #ifdef WORDS_BIGENDIAN
  5091. const uint64_t res_be = 0x8877665544332211;
  5092. #else
  5093. const uint64_t res_le = 0x1122334455667788;
  5094. #endif
  5095. tt_u64_op(0, OP_EQ, tor_htonll(0));
  5096. tt_u64_op(0, OP_EQ, tor_ntohll(0));
  5097. tt_u64_op(UINT64_MAX, OP_EQ, tor_htonll(UINT64_MAX));
  5098. tt_u64_op(UINT64_MAX, OP_EQ, tor_ntohll(UINT64_MAX));
  5099. #ifdef WORDS_BIGENDIAN
  5100. tt_u64_op(res_be, OP_EQ, tor_htonll(0x8877665544332211));
  5101. tt_u64_op(res_be, OP_EQ, tor_ntohll(0x8877665544332211));
  5102. #else
  5103. tt_u64_op(res_le, OP_EQ, tor_htonll(0x8877665544332211));
  5104. tt_u64_op(res_le, OP_EQ, tor_ntohll(0x8877665544332211));
  5105. #endif /* defined(WORDS_BIGENDIAN) */
  5106. done:
  5107. ;
  5108. }
  5109. static void
  5110. test_util_get_unquoted_path(void *arg)
  5111. {
  5112. (void)arg;
  5113. char *r = NULL;
  5114. r = get_unquoted_path("\""); // "
  5115. tt_ptr_op(r, OP_EQ, NULL);
  5116. tor_free(r);
  5117. r = get_unquoted_path("\"\"\""); // """
  5118. tt_ptr_op(r, OP_EQ, NULL);
  5119. tor_free(r);
  5120. r = get_unquoted_path("\\\""); // \"
  5121. tt_ptr_op(r, OP_EQ, NULL);
  5122. tor_free(r);
  5123. r = get_unquoted_path("\\\"\\\""); // \"\"
  5124. tt_ptr_op(r, OP_EQ, NULL);
  5125. tor_free(r);
  5126. r = get_unquoted_path("A\\B\\C\""); // A\B\C"
  5127. tt_ptr_op(r, OP_EQ, NULL);
  5128. tor_free(r);
  5129. r = get_unquoted_path("\"A\\B\\C"); // "A\B\C
  5130. tt_ptr_op(r, OP_EQ, NULL);
  5131. tor_free(r);
  5132. r = get_unquoted_path("\"A\\B\"C\""); // "A\B"C"
  5133. tt_ptr_op(r, OP_EQ, NULL);
  5134. tor_free(r);
  5135. r = get_unquoted_path("A\\B\"C"); // A\B"C
  5136. tt_ptr_op(r, OP_EQ, NULL);
  5137. tor_free(r);
  5138. r = get_unquoted_path("");
  5139. tt_str_op(r, OP_EQ, "");
  5140. tor_free(r);
  5141. r = get_unquoted_path("\"\""); // ""
  5142. tt_str_op(r, OP_EQ, "");
  5143. tor_free(r);
  5144. r = get_unquoted_path("A\\B\\C"); // A\B\C
  5145. tt_str_op(r, OP_EQ, "A\\B\\C"); // A\B\C
  5146. tor_free(r);
  5147. r = get_unquoted_path("\"A\\B\\C\""); // "A\B\C"
  5148. tt_str_op(r, OP_EQ, "A\\B\\C"); // A\B\C
  5149. tor_free(r);
  5150. r = get_unquoted_path("\"\\\""); // "\"
  5151. tt_str_op(r, OP_EQ, "\\"); // \ /* comment to prevent line continuation */
  5152. tor_free(r);
  5153. r = get_unquoted_path("\"\\\"\""); // "\""
  5154. tt_str_op(r, OP_EQ, "\""); // "
  5155. tor_free(r);
  5156. r = get_unquoted_path("\"A\\B\\C\\\"\""); // "A\B\C\""
  5157. tt_str_op(r, OP_EQ, "A\\B\\C\""); // A\B\C"
  5158. tor_free(r);
  5159. r = get_unquoted_path("A\\B\\\"C"); // A\B\"C
  5160. tt_str_op(r, OP_EQ, "A\\B\"C"); // A\B"C
  5161. tor_free(r);
  5162. r = get_unquoted_path("\"A\\B\\\"C\""); // "A\B\"C"
  5163. tt_str_op(r, OP_EQ, "A\\B\"C"); // A\B"C
  5164. done:
  5165. tor_free(r);
  5166. }
  5167. static void
  5168. test_util_log_mallinfo(void *arg)
  5169. {
  5170. (void)arg;
  5171. char *log1 = NULL, *log2 = NULL, *mem = NULL;
  5172. #ifdef HAVE_MALLINFO
  5173. setup_capture_of_logs(LOG_INFO);
  5174. tor_log_mallinfo(LOG_INFO);
  5175. expect_single_log_msg_containing("mallinfo() said: ");
  5176. mock_saved_log_entry_t *lg = smartlist_get(mock_saved_logs(), 0);
  5177. log1 = tor_strdup(lg->generated_msg);
  5178. mock_clean_saved_logs();
  5179. mem = tor_malloc(8192);
  5180. tor_log_mallinfo(LOG_INFO);
  5181. expect_single_log_msg_containing("mallinfo() said: ");
  5182. lg = smartlist_get(mock_saved_logs(), 0);
  5183. log2 = tor_strdup(lg->generated_msg);
  5184. /* Make sure that the amount of used memory increased. */
  5185. const char *used1 = strstr(log1, "uordblks=");
  5186. const char *used2 = strstr(log2, "uordblks=");
  5187. tt_assert(used1);
  5188. tt_assert(used2);
  5189. used1 += strlen("uordblks=");
  5190. used2 += strlen("uordblks=");
  5191. int ok1, ok2;
  5192. char *next1 = NULL, *next2 = NULL;
  5193. uint64_t mem1 = tor_parse_uint64(used1, 10, 0, UINT64_MAX, &ok1, &next1);
  5194. uint64_t mem2 = tor_parse_uint64(used2, 10, 0, UINT64_MAX, &ok2, &next2);
  5195. tt_assert(ok1);
  5196. tt_assert(ok2);
  5197. tt_assert(next1);
  5198. tt_assert(next2);
  5199. if (mem2 == 0) {
  5200. /* This is a fake mallinfo that doesn't actually fill in its outputs. */
  5201. tt_u64_op(mem1, OP_EQ, 0);
  5202. } else {
  5203. tt_u64_op(mem1, OP_LT, mem2);
  5204. }
  5205. #else /* !defined(HAVE_MALLINFO) */
  5206. tt_skip();
  5207. #endif /* defined(HAVE_MALLINFO) */
  5208. done:
  5209. teardown_capture_of_logs();
  5210. tor_free(log1);
  5211. tor_free(log2);
  5212. tor_free(mem);
  5213. }
  5214. static void
  5215. test_util_map_anon(void *arg)
  5216. {
  5217. (void)arg;
  5218. char *ptr = NULL;
  5219. size_t sz = 16384;
  5220. unsigned inherit=0;
  5221. /* Basic checks. */
  5222. ptr = tor_mmap_anonymous(sz, 0, &inherit);
  5223. tt_ptr_op(ptr, OP_NE, 0);
  5224. tt_int_op(inherit, OP_EQ, INHERIT_RES_KEEP);
  5225. ptr[sz-1] = 3;
  5226. tt_int_op(ptr[0], OP_EQ, 0);
  5227. tt_int_op(ptr[sz-2], OP_EQ, 0);
  5228. tt_int_op(ptr[sz-1], OP_EQ, 3);
  5229. /* Try again, with a private (non-swappable) mapping. */
  5230. tor_munmap_anonymous(ptr, sz);
  5231. ptr = tor_mmap_anonymous(sz, ANONMAP_PRIVATE, &inherit);
  5232. tt_ptr_op(ptr, OP_NE, 0);
  5233. tt_int_op(inherit, OP_EQ, INHERIT_RES_KEEP);
  5234. ptr[sz-1] = 10;
  5235. tt_int_op(ptr[0], OP_EQ, 0);
  5236. tt_int_op(ptr[sz/2], OP_EQ, 0);
  5237. tt_int_op(ptr[sz-1], OP_EQ, 10);
  5238. /* Now let's test a drop-on-fork mapping. */
  5239. tor_munmap_anonymous(ptr, sz);
  5240. ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT, &inherit);
  5241. tt_ptr_op(ptr, OP_NE, 0);
  5242. ptr[sz-1] = 10;
  5243. tt_int_op(ptr[0], OP_EQ, 0);
  5244. tt_int_op(ptr[sz/2], OP_EQ, 0);
  5245. tt_int_op(ptr[sz-1], OP_EQ, 10);
  5246. done:
  5247. tor_munmap_anonymous(ptr, sz);
  5248. }
  5249. static void
  5250. test_util_map_anon_nofork(void *arg)
  5251. {
  5252. (void)arg;
  5253. #ifdef _WIN32
  5254. /* The operating system doesn't support forking. */
  5255. tt_skip();
  5256. done:
  5257. ;
  5258. #else /* !defined(_WIN32) */
  5259. /* We have the right OS support. We're going to try marking the buffer as
  5260. * either zero-on-fork or as drop-on-fork, whichever is supported. Then we
  5261. * will fork and send a byte back to the parent process. This will either
  5262. * crash, or send zero. */
  5263. char *ptr = NULL;
  5264. const char TEST_VALUE = 0xd0;
  5265. size_t sz = 16384;
  5266. int pipefd[2] = {-1, -1};
  5267. unsigned inherit=0;
  5268. tor_munmap_anonymous(ptr, sz);
  5269. ptr = tor_mmap_anonymous(sz, ANONMAP_NOINHERIT, &inherit);
  5270. tt_ptr_op(ptr, OP_NE, 0);
  5271. memset(ptr, (uint8_t)TEST_VALUE, sz);
  5272. tt_int_op(0, OP_EQ, pipe(pipefd));
  5273. pid_t child = fork();
  5274. if (child == 0) {
  5275. /* We're in the child. */
  5276. close(pipefd[0]);
  5277. ssize_t r = write(pipefd[1], &ptr[sz-1], 1); /* This may crash. */
  5278. close(pipefd[1]);
  5279. if (r < 0)
  5280. exit(1);
  5281. exit(0);
  5282. }
  5283. tt_int_op(child, OP_GT, 0);
  5284. /* In the parent. */
  5285. close(pipefd[1]);
  5286. pipefd[1] = -1;
  5287. char buf[1];
  5288. ssize_t r = read(pipefd[0], buf, 1);
  5289. if (inherit == INHERIT_RES_ZERO) {
  5290. // We should be seeing clear-on-fork behavior.
  5291. tt_int_op((int)r, OP_EQ, 1); // child should send us a byte.
  5292. tt_int_op(buf[0], OP_EQ, 0); // that byte should be zero.
  5293. } else if (inherit == INHERIT_RES_DROP) {
  5294. // We should be seeing noinherit behavior.
  5295. tt_int_op(r, OP_LE, 0); // child said nothing; it should have crashed.
  5296. } else {
  5297. // noinherit isn't implemented.
  5298. tt_int_op(inherit, OP_EQ, INHERIT_RES_KEEP);
  5299. tt_int_op((int)r, OP_EQ, 1); // child should send us a byte.
  5300. tt_int_op(buf[0], OP_EQ, TEST_VALUE); // that byte should be TEST_VALUE.
  5301. }
  5302. int ws;
  5303. waitpid(child, &ws, 0);
  5304. #ifndef NOINHERIT_CAN_FAIL
  5305. /* Only if NOINHERIT_CAN_FAIL should it be possible for us to get
  5306. * INHERIT_KEEP behavior in this case. */
  5307. tt_int_op(inherit, OP_NE, INHERIT_RES_KEEP);
  5308. #else
  5309. if (inherit == INHERIT_RES_KEEP) {
  5310. /* Call this test "skipped", not "passed", since noinherit wasn't
  5311. * implemented. */
  5312. tt_skip();
  5313. }
  5314. #endif /* !defined(NOINHERIT_CAN_FAIL) */
  5315. done:
  5316. tor_munmap_anonymous(ptr, sz);
  5317. if (pipefd[0] >= 0) {
  5318. close(pipefd[0]);
  5319. }
  5320. if (pipefd[1] >= 0) {
  5321. close(pipefd[1]);
  5322. }
  5323. #endif /* defined(_WIN32) */
  5324. }
  5325. #define UTIL_LEGACY(name) \
  5326. { #name, test_util_ ## name , 0, NULL, NULL }
  5327. #define UTIL_TEST(name, flags) \
  5328. { #name, test_util_ ## name, flags, NULL, NULL }
  5329. #define COMPRESS(name, identifier) \
  5330. { "compress/" #name, test_util_compress, 0, &compress_setup, \
  5331. (char*)(identifier) }
  5332. #define COMPRESS_CONCAT(name, identifier) \
  5333. { "compress_concat/" #name, test_util_decompress_concatenated, 0, \
  5334. &compress_setup, \
  5335. (char*)(identifier) }
  5336. #define COMPRESS_JUNK(name, identifier) \
  5337. { "compress_junk/" #name, test_util_decompress_junk, 0, \
  5338. &compress_setup, \
  5339. (char*)(identifier) }
  5340. #define COMPRESS_DOS(name, identifier) \
  5341. { "compress_dos/" #name, test_util_decompress_dos, 0, \
  5342. &compress_setup, \
  5343. (char*)(identifier) }
  5344. #ifdef _WIN32
  5345. #define UTIL_TEST_NO_WIN(n, f) { #n, NULL, TT_SKIP, NULL, NULL }
  5346. #define UTIL_TEST_WIN_ONLY(n, f) UTIL_TEST(n, (f))
  5347. #define UTIL_LEGACY_NO_WIN(n) UTIL_TEST_NO_WIN(n, 0)
  5348. #else
  5349. #define UTIL_TEST_NO_WIN(n, f) UTIL_TEST(n, (f))
  5350. #define UTIL_TEST_WIN_ONLY(n, f) { #n, NULL, TT_SKIP, NULL, NULL }
  5351. #define UTIL_LEGACY_NO_WIN(n) UTIL_LEGACY(n)
  5352. #endif /* defined(_WIN32) */
  5353. struct testcase_t util_tests[] = {
  5354. UTIL_LEGACY(time),
  5355. UTIL_TEST(parse_http_time, 0),
  5356. UTIL_LEGACY(config_line),
  5357. UTIL_LEGACY(config_line_quotes),
  5358. UTIL_LEGACY(config_line_comment_character),
  5359. UTIL_LEGACY(config_line_escaped_content),
  5360. UTIL_LEGACY(config_line_crlf),
  5361. UTIL_LEGACY_NO_WIN(expand_filename),
  5362. UTIL_LEGACY(escape_string_socks),
  5363. UTIL_LEGACY(string_is_key_value),
  5364. UTIL_LEGACY(strmisc),
  5365. UTIL_TEST(parse_integer, 0),
  5366. UTIL_LEGACY(pow2),
  5367. COMPRESS(zlib, "deflate"),
  5368. COMPRESS(gzip, "gzip"),
  5369. COMPRESS(lzma, "x-tor-lzma"),
  5370. COMPRESS(zstd, "x-zstd"),
  5371. COMPRESS(zstd_nostatic, "x-zstd:nostatic"),
  5372. COMPRESS(none, "identity"),
  5373. COMPRESS_CONCAT(zlib, "deflate"),
  5374. COMPRESS_CONCAT(gzip, "gzip"),
  5375. COMPRESS_CONCAT(lzma, "x-tor-lzma"),
  5376. COMPRESS_CONCAT(zstd, "x-zstd"),
  5377. COMPRESS_CONCAT(zstd_nostatic, "x-zstd:nostatic"),
  5378. COMPRESS_CONCAT(none, "identity"),
  5379. COMPRESS_JUNK(zlib, "deflate"),
  5380. COMPRESS_JUNK(gzip, "gzip"),
  5381. COMPRESS_JUNK(lzma, "x-tor-lzma"),
  5382. COMPRESS_DOS(zlib, "deflate"),
  5383. COMPRESS_DOS(gzip, "gzip"),
  5384. COMPRESS_DOS(lzma, "x-tor-lzma"),
  5385. COMPRESS_DOS(zstd, "x-zstd"),
  5386. COMPRESS_DOS(zstd_nostatic, "x-zstd:nostatic"),
  5387. UTIL_TEST(gzip_compression_bomb, TT_FORK),
  5388. UTIL_LEGACY(datadir),
  5389. UTIL_LEGACY(memarea),
  5390. UTIL_LEGACY(control_formats),
  5391. UTIL_LEGACY(mmap),
  5392. UTIL_TEST(sscanf, TT_FORK),
  5393. UTIL_LEGACY(format_time_interval),
  5394. UTIL_LEGACY(path_is_relative),
  5395. UTIL_LEGACY(strtok),
  5396. UTIL_LEGACY(di_ops),
  5397. UTIL_TEST(di_map, 0),
  5398. UTIL_TEST(round_to_next_multiple_of, 0),
  5399. UTIL_TEST(laplace, 0),
  5400. UTIL_TEST(clamp_double_to_int64, 0),
  5401. UTIL_TEST(find_str_at_start_of_line, 0),
  5402. UTIL_TEST(string_is_C_identifier, 0),
  5403. UTIL_TEST(string_is_utf8, 0),
  5404. UTIL_TEST(asprintf, 0),
  5405. UTIL_TEST(listdir, 0),
  5406. UTIL_TEST(parent_dir, 0),
  5407. UTIL_TEST(ftruncate, 0),
  5408. UTIL_TEST(nowrap_math, 0),
  5409. UTIL_TEST(num_cpus, 0),
  5410. UTIL_TEST_WIN_ONLY(load_win_lib, 0),
  5411. UTIL_TEST(format_hex_number, 0),
  5412. UTIL_TEST(format_dec_number, 0),
  5413. UTIL_TEST(n_bits_set, 0),
  5414. UTIL_TEST(eat_whitespace, 0),
  5415. UTIL_TEST(sl_new_from_text_lines, 0),
  5416. UTIL_TEST(envnames, 0),
  5417. UTIL_TEST(make_environment, 0),
  5418. UTIL_TEST(set_env_var_in_sl, 0),
  5419. UTIL_TEST(read_file_eof_tiny_limit, 0),
  5420. UTIL_TEST(read_file_eof_one_loop_a, 0),
  5421. UTIL_TEST(read_file_eof_one_loop_b, 0),
  5422. UTIL_TEST(read_file_eof_two_loops, 0),
  5423. UTIL_TEST(read_file_eof_two_loops_b, 0),
  5424. UTIL_TEST(read_file_eof_zero_bytes, 0),
  5425. UTIL_TEST(write_chunks_to_file, 0),
  5426. UTIL_TEST(mathlog, 0),
  5427. UTIL_TEST(fraction, 0),
  5428. UTIL_TEST(weak_random, 0),
  5429. { "tor_isinf", test_tor_isinf, TT_FORK, NULL, NULL },
  5430. { "socket_ipv4", test_util_socket, TT_FORK, &passthrough_setup,
  5431. (void*)"4" },
  5432. { "socket_ipv6", test_util_socket, TT_FORK,
  5433. &passthrough_setup, (void*)"6" },
  5434. { "socketpair", test_util_socketpair, TT_FORK, &passthrough_setup,
  5435. (void*)"0" },
  5436. { "socketpair_ersatz", test_util_socketpair, TT_FORK,
  5437. &passthrough_setup, (void*)"1" },
  5438. UTIL_TEST(max_mem, 0),
  5439. UTIL_TEST(hostname_validation, 0),
  5440. UTIL_TEST(dest_validation_edgecase, 0),
  5441. UTIL_TEST(ipv4_validation, 0),
  5442. UTIL_TEST(ipv6_validation, 0),
  5443. UTIL_TEST(writepid, 0),
  5444. UTIL_TEST(get_avail_disk_space, 0),
  5445. UTIL_TEST(touch_file, 0),
  5446. UTIL_TEST_NO_WIN(pwdb, TT_FORK),
  5447. UTIL_TEST(calloc_check, 0),
  5448. UTIL_TEST(monotonic_time, 0),
  5449. UTIL_TEST(monotonic_time_ratchet, TT_FORK),
  5450. UTIL_TEST(monotonic_time_zero, 0),
  5451. UTIL_TEST(monotonic_time_add_msec, 0),
  5452. UTIL_TEST(htonll, 0),
  5453. UTIL_TEST(get_unquoted_path, 0),
  5454. UTIL_TEST(log_mallinfo, 0),
  5455. UTIL_TEST(map_anon, 0),
  5456. UTIL_TEST(map_anon_nofork, 0),
  5457. END_OF_TESTCASES
  5458. };