regexec.c 91 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807
  1. /**********************************************************************
  2. regexec.c - Oniguruma (regular expression library)
  3. **********************************************************************/
  4. /*-
  5. * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in the
  15. * documentation and/or other materials provided with the distribution.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27. * SUCH DAMAGE.
  28. */
  29. #include "regint.h"
  30. #define USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
  31. #ifdef USE_CRNL_AS_LINE_TERMINATOR
  32. #define ONIGENC_IS_MBC_CRNL(enc,p,end) \
  33. (ONIGENC_MBC_TO_CODE(enc,p,end) == 13 && \
  34. ONIGENC_IS_MBC_NEWLINE(enc,(p+enclen(enc,p)),end))
  35. #endif
  36. #ifdef USE_CAPTURE_HISTORY
  37. static void history_tree_free(OnigCaptureTreeNode* node);
  38. static void
  39. history_tree_clear(OnigCaptureTreeNode* node)
  40. {
  41. int i;
  42. if (IS_NOT_NULL(node)) {
  43. for (i = 0; i < node->num_childs; i++) {
  44. if (IS_NOT_NULL(node->childs[i])) {
  45. history_tree_free(node->childs[i]);
  46. }
  47. }
  48. for (i = 0; i < node->allocated; i++) {
  49. node->childs[i] = (OnigCaptureTreeNode* )0;
  50. }
  51. node->num_childs = 0;
  52. node->beg = ONIG_REGION_NOTPOS;
  53. node->end = ONIG_REGION_NOTPOS;
  54. node->group = -1;
  55. }
  56. }
  57. static void
  58. history_tree_free(OnigCaptureTreeNode* node)
  59. {
  60. history_tree_clear(node);
  61. xfree(node);
  62. }
  63. static void
  64. history_root_free(OnigRegion* r)
  65. {
  66. if (IS_NOT_NULL(r->history_root)) {
  67. history_tree_free(r->history_root);
  68. r->history_root = (OnigCaptureTreeNode* )0;
  69. }
  70. }
  71. static OnigCaptureTreeNode*
  72. history_node_new(void)
  73. {
  74. OnigCaptureTreeNode* node;
  75. node = (OnigCaptureTreeNode* )xmalloc(sizeof(OnigCaptureTreeNode));
  76. CHECK_NULL_RETURN(node);
  77. node->childs = (OnigCaptureTreeNode** )0;
  78. node->allocated = 0;
  79. node->num_childs = 0;
  80. node->group = -1;
  81. node->beg = ONIG_REGION_NOTPOS;
  82. node->end = ONIG_REGION_NOTPOS;
  83. return node;
  84. }
  85. static int
  86. history_tree_add_child(OnigCaptureTreeNode* parent, OnigCaptureTreeNode* child)
  87. {
  88. #define HISTORY_TREE_INIT_ALLOC_SIZE 8
  89. if (parent->num_childs >= parent->allocated) {
  90. int n, i;
  91. if (IS_NULL(parent->childs)) {
  92. n = HISTORY_TREE_INIT_ALLOC_SIZE;
  93. parent->childs =
  94. (OnigCaptureTreeNode** )xmalloc(sizeof(OnigCaptureTreeNode*) * n);
  95. }
  96. else {
  97. n = parent->allocated * 2;
  98. parent->childs =
  99. (OnigCaptureTreeNode** )xrealloc(parent->childs,
  100. sizeof(OnigCaptureTreeNode*) * n);
  101. }
  102. CHECK_NULL_RETURN_MEMERR(parent->childs);
  103. for (i = parent->allocated; i < n; i++) {
  104. parent->childs[i] = (OnigCaptureTreeNode* )0;
  105. }
  106. parent->allocated = n;
  107. }
  108. parent->childs[parent->num_childs] = child;
  109. parent->num_childs++;
  110. return 0;
  111. }
  112. static OnigCaptureTreeNode*
  113. history_tree_clone(OnigCaptureTreeNode* node)
  114. {
  115. int i;
  116. OnigCaptureTreeNode *clone, *child;
  117. clone = history_node_new();
  118. CHECK_NULL_RETURN(clone);
  119. clone->beg = node->beg;
  120. clone->end = node->end;
  121. for (i = 0; i < node->num_childs; i++) {
  122. child = history_tree_clone(node->childs[i]);
  123. if (IS_NULL(child)) {
  124. history_tree_free(clone);
  125. return (OnigCaptureTreeNode* )0;
  126. }
  127. history_tree_add_child(clone, child);
  128. }
  129. return clone;
  130. }
  131. extern OnigCaptureTreeNode*
  132. onig_get_capture_tree(OnigRegion* region)
  133. {
  134. return region->history_root;
  135. }
  136. #endif /* USE_CAPTURE_HISTORY */
  137. extern void
  138. onig_region_clear(OnigRegion* region)
  139. {
  140. int i;
  141. for (i = 0; i < region->num_regs; i++) {
  142. region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
  143. }
  144. #ifdef USE_CAPTURE_HISTORY
  145. history_root_free(region);
  146. #endif
  147. }
  148. extern int
  149. onig_region_resize(OnigRegion* region, int n)
  150. {
  151. region->num_regs = n;
  152. if (n < ONIG_NREGION)
  153. n = ONIG_NREGION;
  154. if (region->allocated == 0) {
  155. region->beg = (int* )xmalloc(n * sizeof(int));
  156. region->end = (int* )xmalloc(n * sizeof(int));
  157. if (region->beg == 0 || region->end == 0)
  158. return ONIGERR_MEMORY;
  159. region->allocated = n;
  160. }
  161. else if (region->allocated < n) {
  162. region->beg = (int* )xrealloc(region->beg, n * sizeof(int));
  163. region->end = (int* )xrealloc(region->end, n * sizeof(int));
  164. if (region->beg == 0 || region->end == 0)
  165. return ONIGERR_MEMORY;
  166. region->allocated = n;
  167. }
  168. return 0;
  169. }
  170. static int
  171. onig_region_resize_clear(OnigRegion* region, int n)
  172. {
  173. int r;
  174. r = onig_region_resize(region, n);
  175. if (r != 0) return r;
  176. onig_region_clear(region);
  177. return 0;
  178. }
  179. extern int
  180. onig_region_set(OnigRegion* region, int at, int beg, int end)
  181. {
  182. if (at < 0) return ONIGERR_INVALID_ARGUMENT;
  183. if (at >= region->allocated) {
  184. int r = onig_region_resize(region, at + 1);
  185. if (r < 0) return r;
  186. }
  187. region->beg[at] = beg;
  188. region->end[at] = end;
  189. return 0;
  190. }
  191. extern void
  192. onig_region_init(OnigRegion* region)
  193. {
  194. region->num_regs = 0;
  195. region->allocated = 0;
  196. region->beg = (int* )0;
  197. region->end = (int* )0;
  198. region->history_root = (OnigCaptureTreeNode* )0;
  199. }
  200. extern OnigRegion*
  201. onig_region_new(void)
  202. {
  203. OnigRegion* r;
  204. r = (OnigRegion* )xmalloc(sizeof(OnigRegion));
  205. onig_region_init(r);
  206. return r;
  207. }
  208. extern void
  209. onig_region_free(OnigRegion* r, int free_self)
  210. {
  211. if (r) {
  212. if (r->allocated > 0) {
  213. if (r->beg) xfree(r->beg);
  214. if (r->end) xfree(r->end);
  215. r->allocated = 0;
  216. }
  217. #ifdef USE_CAPTURE_HISTORY
  218. history_root_free(r);
  219. #endif
  220. if (free_self) xfree(r);
  221. }
  222. }
  223. extern void
  224. onig_region_copy(OnigRegion* to, OnigRegion* from)
  225. {
  226. #define RREGC_SIZE (sizeof(int) * from->num_regs)
  227. int i;
  228. if (to == from) return;
  229. if (to->allocated == 0) {
  230. if (from->num_regs > 0) {
  231. to->beg = (int* )xmalloc(RREGC_SIZE);
  232. to->end = (int* )xmalloc(RREGC_SIZE);
  233. to->allocated = from->num_regs;
  234. }
  235. }
  236. else if (to->allocated < from->num_regs) {
  237. to->beg = (int* )xrealloc(to->beg, RREGC_SIZE);
  238. to->end = (int* )xrealloc(to->end, RREGC_SIZE);
  239. to->allocated = from->num_regs;
  240. }
  241. for (i = 0; i < from->num_regs; i++) {
  242. to->beg[i] = from->beg[i];
  243. to->end[i] = from->end[i];
  244. }
  245. to->num_regs = from->num_regs;
  246. #ifdef USE_CAPTURE_HISTORY
  247. history_root_free(to);
  248. if (IS_NOT_NULL(from->history_root)) {
  249. to->history_root = history_tree_clone(from->history_root);
  250. }
  251. #endif
  252. }
  253. /** stack **/
  254. #define INVALID_STACK_INDEX -1
  255. /* stack type */
  256. /* used by normal-POP */
  257. #define STK_ALT 0x0001
  258. #define STK_LOOK_BEHIND_NOT 0x0002
  259. #define STK_POS_NOT 0x0003
  260. /* handled by normal-POP */
  261. #define STK_MEM_START 0x0100
  262. #define STK_MEM_END 0x8200
  263. #define STK_REPEAT_INC 0x0300
  264. #define STK_STATE_CHECK_MARK 0x1000
  265. /* avoided by normal-POP */
  266. #define STK_NULL_CHECK_START 0x3000
  267. #define STK_NULL_CHECK_END 0x5000 /* for recursive call */
  268. #define STK_MEM_END_MARK 0x8400
  269. #define STK_POS 0x0500 /* used when POP-POS */
  270. #define STK_STOP_BT 0x0600 /* mark for "(?>...)" */
  271. #define STK_REPEAT 0x0700
  272. #define STK_CALL_FRAME 0x0800
  273. #define STK_RETURN 0x0900
  274. #define STK_VOID 0x0a00 /* for fill a blank */
  275. /* stack type check mask */
  276. #define STK_MASK_POP_USED 0x00ff
  277. #define STK_MASK_TO_VOID_TARGET 0x10ff
  278. #define STK_MASK_MEM_END_OR_MARK 0x8000 /* MEM_END or MEM_END_MARK */
  279. #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
  280. #define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start) do {\
  281. (msa).stack_p = (void* )0;\
  282. (msa).options = (arg_option);\
  283. (msa).region = (arg_region);\
  284. (msa).start = (arg_start);\
  285. (msa).best_len = ONIG_MISMATCH;\
  286. } while(0)
  287. #else
  288. #define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start) do {\
  289. (msa).stack_p = (void* )0;\
  290. (msa).options = (arg_option);\
  291. (msa).region = (arg_region);\
  292. (msa).start = (arg_start);\
  293. } while(0)
  294. #endif
  295. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  296. #define STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE 16
  297. #define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num) do { \
  298. if ((state_num) > 0 && str_len >= STATE_CHECK_STRING_THRESHOLD_LEN) {\
  299. unsigned int size = (unsigned int )(((str_len) + 1) * (state_num) + 7) >> 3;\
  300. offset = ((offset) * (state_num)) >> 3;\
  301. if (size > 0 && offset < size && size < STATE_CHECK_BUFF_MAX_SIZE) {\
  302. if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) \
  303. (msa).state_check_buff = (void* )xmalloc(size);\
  304. else \
  305. (msa).state_check_buff = (void* )xalloca(size);\
  306. xmemset(((char* )((msa).state_check_buff)+(offset)), 0, \
  307. (size_t )(size - (offset))); \
  308. (msa).state_check_buff_size = size;\
  309. }\
  310. else {\
  311. (msa).state_check_buff = (void* )0;\
  312. (msa).state_check_buff_size = 0;\
  313. }\
  314. }\
  315. else {\
  316. (msa).state_check_buff = (void* )0;\
  317. (msa).state_check_buff_size = 0;\
  318. }\
  319. } while(0)
  320. #define MATCH_ARG_FREE(msa) do {\
  321. if ((msa).stack_p) xfree((msa).stack_p);\
  322. if ((msa).state_check_buff_size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) { \
  323. if ((msa).state_check_buff) xfree((msa).state_check_buff);\
  324. }\
  325. } while(0)
  326. #else
  327. #define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num)
  328. #define MATCH_ARG_FREE(msa) if ((msa).stack_p) xfree((msa).stack_p)
  329. #endif
  330. #define STACK_INIT(alloc_addr, ptr_num, stack_num) do {\
  331. if (msa->stack_p) {\
  332. alloc_addr = (char* )xalloca(sizeof(char*) * (ptr_num));\
  333. stk_alloc = (OnigStackType* )(msa->stack_p);\
  334. stk_base = stk_alloc;\
  335. stk = stk_base;\
  336. stk_end = stk_base + msa->stack_n;\
  337. }\
  338. else {\
  339. alloc_addr = (char* )xalloca(sizeof(char*) * (ptr_num)\
  340. + sizeof(OnigStackType) * (stack_num));\
  341. stk_alloc = (OnigStackType* )(alloc_addr + sizeof(char*) * (ptr_num));\
  342. stk_base = stk_alloc;\
  343. stk = stk_base;\
  344. stk_end = stk_base + (stack_num);\
  345. }\
  346. } while(0)
  347. #define STACK_SAVE do{\
  348. if (stk_base != stk_alloc) {\
  349. msa->stack_p = stk_base;\
  350. msa->stack_n = stk_end - stk_base;\
  351. };\
  352. } while(0)
  353. static unsigned int MatchStackLimitSize = DEFAULT_MATCH_STACK_LIMIT_SIZE;
  354. extern unsigned int
  355. onig_get_match_stack_limit_size(void)
  356. {
  357. return MatchStackLimitSize;
  358. }
  359. extern int
  360. onig_set_match_stack_limit_size(unsigned int size)
  361. {
  362. MatchStackLimitSize = size;
  363. return 0;
  364. }
  365. static int
  366. stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
  367. OnigStackType** arg_stk, OnigStackType* stk_alloc, OnigMatchArg* msa)
  368. {
  369. unsigned int n;
  370. OnigStackType *x, *stk_base, *stk_end, *stk;
  371. stk_base = *arg_stk_base;
  372. stk_end = *arg_stk_end;
  373. stk = *arg_stk;
  374. n = stk_end - stk_base;
  375. if (stk_base == stk_alloc && IS_NULL(msa->stack_p)) {
  376. x = (OnigStackType* )xmalloc(sizeof(OnigStackType) * n * 2);
  377. if (IS_NULL(x)) {
  378. STACK_SAVE;
  379. return ONIGERR_MEMORY;
  380. }
  381. xmemcpy(x, stk_base, n * sizeof(OnigStackType));
  382. n *= 2;
  383. }
  384. else {
  385. n *= 2;
  386. if (MatchStackLimitSize != 0 && n > MatchStackLimitSize) {
  387. if ((unsigned int )(stk_end - stk_base) == MatchStackLimitSize)
  388. return ONIGERR_MATCH_STACK_LIMIT_OVER;
  389. else
  390. n = MatchStackLimitSize;
  391. }
  392. x = (OnigStackType* )xrealloc(stk_base, sizeof(OnigStackType) * n);
  393. if (IS_NULL(x)) {
  394. STACK_SAVE;
  395. return ONIGERR_MEMORY;
  396. }
  397. }
  398. *arg_stk = x + (stk - stk_base);
  399. *arg_stk_base = x;
  400. *arg_stk_end = x + n;
  401. return 0;
  402. }
  403. #define STACK_ENSURE(n) do {\
  404. if (stk_end - stk < (n)) {\
  405. int r = stack_double(&stk_base, &stk_end, &stk, stk_alloc, msa);\
  406. if (r != 0) { STACK_SAVE; return r; } \
  407. }\
  408. } while(0)
  409. #define STACK_AT(index) (stk_base + (index))
  410. #define GET_STACK_INDEX(stk) ((stk) - stk_base)
  411. #define STACK_PUSH_TYPE(stack_type) do {\
  412. STACK_ENSURE(1);\
  413. stk->type = (stack_type);\
  414. STACK_INC;\
  415. } while(0)
  416. #define IS_TO_VOID_TARGET(stk) (((stk)->type & STK_MASK_TO_VOID_TARGET) != 0)
  417. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  418. #define STATE_CHECK_POS(s,snum) \
  419. (((s) - str) * num_comb_exp_check + ((snum) - 1))
  420. #define STATE_CHECK_VAL(v,snum) do {\
  421. if (state_check_buff != NULL) {\
  422. int x = STATE_CHECK_POS(s,snum);\
  423. (v) = state_check_buff[x/8] & (1<<(x%8));\
  424. }\
  425. else (v) = 0;\
  426. } while(0)
  427. #define ELSE_IF_STATE_CHECK_MARK(stk) \
  428. else if ((stk)->type == STK_STATE_CHECK_MARK) { \
  429. int x = STATE_CHECK_POS(stk->u.state.pstr, stk->u.state.state_check);\
  430. state_check_buff[x/8] |= (1<<(x%8)); \
  431. }
  432. #define STACK_PUSH(stack_type,pat,s,sprev) do {\
  433. STACK_ENSURE(1);\
  434. stk->type = (stack_type);\
  435. stk->u.state.pcode = (pat);\
  436. stk->u.state.pstr = (s);\
  437. stk->u.state.pstr_prev = (sprev);\
  438. stk->u.state.state_check = 0;\
  439. STACK_INC;\
  440. } while(0)
  441. #define STACK_PUSH_ENSURED(stack_type,pat) do {\
  442. stk->type = (stack_type);\
  443. stk->u.state.pcode = (pat);\
  444. stk->u.state.state_check = 0;\
  445. STACK_INC;\
  446. } while(0)
  447. #define STACK_PUSH_ALT_WITH_STATE_CHECK(pat,s,sprev,snum) do {\
  448. STACK_ENSURE(1);\
  449. stk->type = STK_ALT;\
  450. stk->u.state.pcode = (pat);\
  451. stk->u.state.pstr = (s);\
  452. stk->u.state.pstr_prev = (sprev);\
  453. stk->u.state.state_check = ((state_check_buff != NULL) ? (snum) : 0);\
  454. STACK_INC;\
  455. } while(0)
  456. #define STACK_PUSH_STATE_CHECK(s,snum) do {\
  457. if (state_check_buff != NULL) {\
  458. STACK_ENSURE(1);\
  459. stk->type = STK_STATE_CHECK_MARK;\
  460. stk->u.state.pstr = (s);\
  461. stk->u.state.state_check = (snum);\
  462. STACK_INC;\
  463. }\
  464. } while(0)
  465. #else /* USE_COMBINATION_EXPLOSION_CHECK */
  466. #define ELSE_IF_STATE_CHECK_MARK(stk)
  467. #define STACK_PUSH(stack_type,pat,s,sprev) do {\
  468. STACK_ENSURE(1);\
  469. stk->type = (stack_type);\
  470. stk->u.state.pcode = (pat);\
  471. stk->u.state.pstr = (s);\
  472. stk->u.state.pstr_prev = (sprev);\
  473. STACK_INC;\
  474. } while(0)
  475. #define STACK_PUSH_ENSURED(stack_type,pat) do {\
  476. stk->type = (stack_type);\
  477. stk->u.state.pcode = (pat);\
  478. STACK_INC;\
  479. } while(0)
  480. #endif /* USE_COMBINATION_EXPLOSION_CHECK */
  481. #define STACK_PUSH_ALT(pat,s,sprev) STACK_PUSH(STK_ALT,pat,s,sprev)
  482. #define STACK_PUSH_POS(s,sprev) STACK_PUSH(STK_POS,NULL_UCHARP,s,sprev)
  483. #define STACK_PUSH_POS_NOT(pat,s,sprev) STACK_PUSH(STK_POS_NOT,pat,s,sprev)
  484. #define STACK_PUSH_STOP_BT STACK_PUSH_TYPE(STK_STOP_BT)
  485. #define STACK_PUSH_LOOK_BEHIND_NOT(pat,s,sprev) \
  486. STACK_PUSH(STK_LOOK_BEHIND_NOT,pat,s,sprev)
  487. #define STACK_PUSH_REPEAT(id, pat) do {\
  488. STACK_ENSURE(1);\
  489. stk->type = STK_REPEAT;\
  490. stk->u.repeat.num = (id);\
  491. stk->u.repeat.pcode = (pat);\
  492. stk->u.repeat.count = 0;\
  493. STACK_INC;\
  494. } while(0)
  495. #define STACK_PUSH_REPEAT_INC(sindex) do {\
  496. STACK_ENSURE(1);\
  497. stk->type = STK_REPEAT_INC;\
  498. stk->u.repeat_inc.si = (sindex);\
  499. STACK_INC;\
  500. } while(0)
  501. #define STACK_PUSH_MEM_START(mnum, s) do {\
  502. STACK_ENSURE(1);\
  503. stk->type = STK_MEM_START;\
  504. stk->u.mem.num = (mnum);\
  505. stk->u.mem.pstr = (s);\
  506. stk->u.mem.start = mem_start_stk[mnum];\
  507. stk->u.mem.end = mem_end_stk[mnum];\
  508. mem_start_stk[mnum] = GET_STACK_INDEX(stk);\
  509. mem_end_stk[mnum] = INVALID_STACK_INDEX;\
  510. STACK_INC;\
  511. } while(0)
  512. #define STACK_PUSH_MEM_END(mnum, s) do {\
  513. STACK_ENSURE(1);\
  514. stk->type = STK_MEM_END;\
  515. stk->u.mem.num = (mnum);\
  516. stk->u.mem.pstr = (s);\
  517. stk->u.mem.start = mem_start_stk[mnum];\
  518. stk->u.mem.end = mem_end_stk[mnum];\
  519. mem_end_stk[mnum] = GET_STACK_INDEX(stk);\
  520. STACK_INC;\
  521. } while(0)
  522. #define STACK_PUSH_MEM_END_MARK(mnum) do {\
  523. STACK_ENSURE(1);\
  524. stk->type = STK_MEM_END_MARK;\
  525. stk->u.mem.num = (mnum);\
  526. STACK_INC;\
  527. } while(0)
  528. #define STACK_GET_MEM_START(mnum, k) do {\
  529. int level = 0;\
  530. k = stk;\
  531. while (k > stk_base) {\
  532. k--;\
  533. if ((k->type & STK_MASK_MEM_END_OR_MARK) != 0 \
  534. && k->u.mem.num == (mnum)) {\
  535. level++;\
  536. }\
  537. else if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
  538. if (level == 0) break;\
  539. level--;\
  540. }\
  541. }\
  542. } while(0)
  543. #define STACK_GET_MEM_RANGE(k, mnum, start, end) do {\
  544. int level = 0;\
  545. while (k < stk) {\
  546. if (k->type == STK_MEM_START && k->u.mem.num == (mnum)) {\
  547. if (level == 0) (start) = k->u.mem.pstr;\
  548. level++;\
  549. }\
  550. else if (k->type == STK_MEM_END && k->u.mem.num == (mnum)) {\
  551. level--;\
  552. if (level == 0) {\
  553. (end) = k->u.mem.pstr;\
  554. break;\
  555. }\
  556. }\
  557. k++;\
  558. }\
  559. } while(0)
  560. #define STACK_PUSH_NULL_CHECK_START(cnum, s) do {\
  561. STACK_ENSURE(1);\
  562. stk->type = STK_NULL_CHECK_START;\
  563. stk->u.null_check.num = (cnum);\
  564. stk->u.null_check.pstr = (s);\
  565. STACK_INC;\
  566. } while(0)
  567. #define STACK_PUSH_NULL_CHECK_END(cnum) do {\
  568. STACK_ENSURE(1);\
  569. stk->type = STK_NULL_CHECK_END;\
  570. stk->u.null_check.num = (cnum);\
  571. STACK_INC;\
  572. } while(0)
  573. #define STACK_PUSH_CALL_FRAME(pat) do {\
  574. STACK_ENSURE(1);\
  575. stk->type = STK_CALL_FRAME;\
  576. stk->u.call_frame.ret_addr = (pat);\
  577. STACK_INC;\
  578. } while(0)
  579. #define STACK_PUSH_RETURN do {\
  580. STACK_ENSURE(1);\
  581. stk->type = STK_RETURN;\
  582. STACK_INC;\
  583. } while(0)
  584. #ifdef ONIG_DEBUG
  585. #define STACK_BASE_CHECK(p, at) \
  586. if ((p) < stk_base) {\
  587. fprintf(stderr, "at %s\n", at);\
  588. goto stack_error;\
  589. }
  590. #else
  591. #define STACK_BASE_CHECK(p, at)
  592. #endif
  593. #define STACK_POP_ONE do {\
  594. stk--;\
  595. STACK_BASE_CHECK(stk, "STACK_POP_ONE"); \
  596. } while(0)
  597. #define STACK_POP do {\
  598. switch (pop_level) {\
  599. case STACK_POP_LEVEL_FREE:\
  600. while (1) {\
  601. stk--;\
  602. STACK_BASE_CHECK(stk, "STACK_POP"); \
  603. if ((stk->type & STK_MASK_POP_USED) != 0) break;\
  604. ELSE_IF_STATE_CHECK_MARK(stk);\
  605. }\
  606. break;\
  607. case STACK_POP_LEVEL_MEM_START:\
  608. while (1) {\
  609. stk--;\
  610. STACK_BASE_CHECK(stk, "STACK_POP 2"); \
  611. if ((stk->type & STK_MASK_POP_USED) != 0) break;\
  612. else if (stk->type == STK_MEM_START) {\
  613. mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
  614. mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
  615. }\
  616. ELSE_IF_STATE_CHECK_MARK(stk);\
  617. }\
  618. break;\
  619. default:\
  620. while (1) {\
  621. stk--;\
  622. STACK_BASE_CHECK(stk, "STACK_POP 3"); \
  623. if ((stk->type & STK_MASK_POP_USED) != 0) break;\
  624. else if (stk->type == STK_MEM_START) {\
  625. mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
  626. mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
  627. }\
  628. else if (stk->type == STK_REPEAT_INC) {\
  629. STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
  630. }\
  631. else if (stk->type == STK_MEM_END) {\
  632. mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
  633. mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
  634. }\
  635. ELSE_IF_STATE_CHECK_MARK(stk);\
  636. }\
  637. break;\
  638. }\
  639. } while(0)
  640. #define STACK_POP_TIL_POS_NOT do {\
  641. while (1) {\
  642. stk--;\
  643. STACK_BASE_CHECK(stk, "STACK_POP_TIL_POS_NOT"); \
  644. if (stk->type == STK_POS_NOT) break;\
  645. else if (stk->type == STK_MEM_START) {\
  646. mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
  647. mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
  648. }\
  649. else if (stk->type == STK_REPEAT_INC) {\
  650. STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
  651. }\
  652. else if (stk->type == STK_MEM_END) {\
  653. mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
  654. mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
  655. }\
  656. ELSE_IF_STATE_CHECK_MARK(stk);\
  657. }\
  658. } while(0)
  659. #define STACK_POP_TIL_LOOK_BEHIND_NOT do {\
  660. while (1) {\
  661. stk--;\
  662. STACK_BASE_CHECK(stk, "STACK_POP_TIL_LOOK_BEHIND_NOT"); \
  663. if (stk->type == STK_LOOK_BEHIND_NOT) break;\
  664. else if (stk->type == STK_MEM_START) {\
  665. mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
  666. mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
  667. }\
  668. else if (stk->type == STK_REPEAT_INC) {\
  669. STACK_AT(stk->u.repeat_inc.si)->u.repeat.count--;\
  670. }\
  671. else if (stk->type == STK_MEM_END) {\
  672. mem_start_stk[stk->u.mem.num] = stk->u.mem.start;\
  673. mem_end_stk[stk->u.mem.num] = stk->u.mem.end;\
  674. }\
  675. ELSE_IF_STATE_CHECK_MARK(stk);\
  676. }\
  677. } while(0)
  678. #define STACK_POS_END(k) do {\
  679. k = stk;\
  680. while (1) {\
  681. k--;\
  682. STACK_BASE_CHECK(k, "STACK_POS_END"); \
  683. if (IS_TO_VOID_TARGET(k)) {\
  684. k->type = STK_VOID;\
  685. }\
  686. else if (k->type == STK_POS) {\
  687. k->type = STK_VOID;\
  688. break;\
  689. }\
  690. }\
  691. } while(0)
  692. #define STACK_STOP_BT_END do {\
  693. OnigStackType *k = stk;\
  694. while (1) {\
  695. k--;\
  696. STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \
  697. if (IS_TO_VOID_TARGET(k)) {\
  698. k->type = STK_VOID;\
  699. }\
  700. else if (k->type == STK_STOP_BT) {\
  701. k->type = STK_VOID;\
  702. break;\
  703. }\
  704. }\
  705. } while(0)
  706. #define STACK_NULL_CHECK(isnull,id,s) do {\
  707. OnigStackType* k = stk;\
  708. while (1) {\
  709. k--;\
  710. STACK_BASE_CHECK(k, "STACK_NULL_CHECK"); \
  711. if (k->type == STK_NULL_CHECK_START) {\
  712. if (k->u.null_check.num == (id)) {\
  713. (isnull) = (k->u.null_check.pstr == (s));\
  714. break;\
  715. }\
  716. }\
  717. }\
  718. } while(0)
  719. #define STACK_NULL_CHECK_REC(isnull,id,s) do {\
  720. int level = 0;\
  721. OnigStackType* k = stk;\
  722. while (1) {\
  723. k--;\
  724. STACK_BASE_CHECK(k, "STACK_NULL_CHECK_REC"); \
  725. if (k->type == STK_NULL_CHECK_START) {\
  726. if (k->u.null_check.num == (id)) {\
  727. if (level == 0) {\
  728. (isnull) = (k->u.null_check.pstr == (s));\
  729. break;\
  730. }\
  731. else level--;\
  732. }\
  733. }\
  734. else if (k->type == STK_NULL_CHECK_END) {\
  735. level++;\
  736. }\
  737. }\
  738. } while(0)
  739. #define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\
  740. OnigStackType* k = stk;\
  741. while (1) {\
  742. k--;\
  743. STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST"); \
  744. if (k->type == STK_NULL_CHECK_START) {\
  745. if (k->u.null_check.num == (id)) {\
  746. if (k->u.null_check.pstr != (s)) {\
  747. (isnull) = 0;\
  748. break;\
  749. }\
  750. else {\
  751. UChar* endp;\
  752. (isnull) = 1;\
  753. while (k < stk) {\
  754. if (k->type == STK_MEM_START) {\
  755. if (k->u.mem.end == INVALID_STACK_INDEX) {\
  756. (isnull) = 0; break;\
  757. }\
  758. if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
  759. endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
  760. else\
  761. endp = (UChar* )k->u.mem.end;\
  762. if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
  763. (isnull) = 0; break;\
  764. }\
  765. else if (endp != s) {\
  766. (isnull) = -1; /* empty, but position changed */ \
  767. }\
  768. }\
  769. k++;\
  770. }\
  771. break;\
  772. }\
  773. }\
  774. }\
  775. }\
  776. } while(0)
  777. #define STACK_NULL_CHECK_MEMST_REC(isnull,id,s,reg) do {\
  778. int level = 0;\
  779. OnigStackType* k = stk;\
  780. while (1) {\
  781. k--;\
  782. STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST_REC"); \
  783. if (k->type == STK_NULL_CHECK_START) {\
  784. if (k->u.null_check.num == (id)) {\
  785. if (level == 0) {\
  786. if (k->u.null_check.pstr != (s)) {\
  787. (isnull) = 0;\
  788. break;\
  789. }\
  790. else {\
  791. UChar* endp;\
  792. (isnull) = 1;\
  793. while (k < stk) {\
  794. if (k->type == STK_MEM_START) {\
  795. if (k->u.mem.end == INVALID_STACK_INDEX) {\
  796. (isnull) = 0; break;\
  797. }\
  798. if (BIT_STATUS_AT(reg->bt_mem_end, k->u.mem.num))\
  799. endp = STACK_AT(k->u.mem.end)->u.mem.pstr;\
  800. else\
  801. endp = (UChar* )k->u.mem.end;\
  802. if (STACK_AT(k->u.mem.start)->u.mem.pstr != endp) {\
  803. (isnull) = 0; break;\
  804. }\
  805. else if (endp != s) {\
  806. (isnull) = -1; /* empty, but position changed */ \
  807. }\
  808. }\
  809. k++;\
  810. }\
  811. break;\
  812. }\
  813. }\
  814. else {\
  815. level--;\
  816. }\
  817. }\
  818. }\
  819. else if (k->type == STK_NULL_CHECK_END) {\
  820. if (k->u.null_check.num == (id)) level++;\
  821. }\
  822. }\
  823. } while(0)
  824. #define STACK_GET_REPEAT(id, k) do {\
  825. int level = 0;\
  826. k = stk;\
  827. while (1) {\
  828. k--;\
  829. STACK_BASE_CHECK(k, "STACK_GET_REPEAT"); \
  830. if (k->type == STK_REPEAT) {\
  831. if (level == 0) {\
  832. if (k->u.repeat.num == (id)) {\
  833. break;\
  834. }\
  835. }\
  836. }\
  837. else if (k->type == STK_CALL_FRAME) level--;\
  838. else if (k->type == STK_RETURN) level++;\
  839. }\
  840. } while(0)
  841. #define STACK_RETURN(addr) do {\
  842. int level = 0;\
  843. OnigStackType* k = stk;\
  844. while (1) {\
  845. k--;\
  846. STACK_BASE_CHECK(k, "STACK_RETURN"); \
  847. if (k->type == STK_CALL_FRAME) {\
  848. if (level == 0) {\
  849. (addr) = k->u.call_frame.ret_addr;\
  850. break;\
  851. }\
  852. else level--;\
  853. }\
  854. else if (k->type == STK_RETURN)\
  855. level++;\
  856. }\
  857. } while(0)
  858. #define STRING_CMP(s1,s2,len) do {\
  859. while (len-- > 0) {\
  860. if (*s1++ != *s2++) goto fail;\
  861. }\
  862. } while(0)
  863. #define STRING_CMP_IC(case_fold_flag,s1,ps2,len) do {\
  864. if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len) == 0) \
  865. goto fail; \
  866. } while(0)
  867. static int string_cmp_ic(OnigEncoding enc, int case_fold_flag,
  868. UChar* s1, UChar** ps2, int mblen)
  869. {
  870. UChar buf1[ONIGENC_MBC_CASE_FOLD_MAXLEN];
  871. UChar buf2[ONIGENC_MBC_CASE_FOLD_MAXLEN];
  872. UChar *p1, *p2, *end1, *s2, *end2;
  873. int len1, len2;
  874. s2 = *ps2;
  875. end1 = s1 + mblen;
  876. end2 = s2 + mblen;
  877. while (s1 < end1) {
  878. len1 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s1, end1, buf1);
  879. len2 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s2, end2, buf2);
  880. if (len1 != len2) return 0;
  881. p1 = buf1;
  882. p2 = buf2;
  883. while (len1-- > 0) {
  884. if (*p1 != *p2) return 0;
  885. p1++;
  886. p2++;
  887. }
  888. }
  889. *ps2 = s2;
  890. return 1;
  891. }
  892. #define STRING_CMP_VALUE(s1,s2,len,is_fail) do {\
  893. is_fail = 0;\
  894. while (len-- > 0) {\
  895. if (*s1++ != *s2++) {\
  896. is_fail = 1; break;\
  897. }\
  898. }\
  899. } while(0)
  900. #define STRING_CMP_VALUE_IC(case_fold_flag,s1,ps2,len,is_fail) do {\
  901. if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len) == 0) \
  902. is_fail = 1; \
  903. else \
  904. is_fail = 0; \
  905. } while(0)
  906. #define IS_EMPTY_STR (str == end)
  907. #define ON_STR_BEGIN(s) ((s) == str)
  908. #define ON_STR_END(s) ((s) == end)
  909. #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
  910. #define DATA_ENSURE_CHECK1 (s < right_range)
  911. #define DATA_ENSURE_CHECK(n) (s + (n) <= right_range)
  912. #define DATA_ENSURE(n) if (s + (n) > right_range) goto fail
  913. #else
  914. #define DATA_ENSURE_CHECK1 (s < end)
  915. #define DATA_ENSURE_CHECK(n) (s + (n) <= end)
  916. #define DATA_ENSURE(n) if (s + (n) > end) goto fail
  917. #endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
  918. #ifdef USE_CAPTURE_HISTORY
  919. static int
  920. make_capture_history_tree(OnigCaptureTreeNode* node, OnigStackType** kp,
  921. OnigStackType* stk_top, UChar* str, regex_t* reg)
  922. {
  923. int n, r;
  924. OnigCaptureTreeNode* child;
  925. OnigStackType* k = *kp;
  926. while (k < stk_top) {
  927. if (k->type == STK_MEM_START) {
  928. n = k->u.mem.num;
  929. if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP &&
  930. BIT_STATUS_AT(reg->capture_history, n) != 0) {
  931. child = history_node_new();
  932. CHECK_NULL_RETURN_MEMERR(child);
  933. child->group = n;
  934. child->beg = (int )(k->u.mem.pstr - str);
  935. r = history_tree_add_child(node, child);
  936. if (r != 0) return r;
  937. *kp = (k + 1);
  938. r = make_capture_history_tree(child, kp, stk_top, str, reg);
  939. if (r != 0) return r;
  940. k = *kp;
  941. child->end = (int )(k->u.mem.pstr - str);
  942. }
  943. }
  944. else if (k->type == STK_MEM_END) {
  945. if (k->u.mem.num == node->group) {
  946. node->end = (int )(k->u.mem.pstr - str);
  947. *kp = k;
  948. return 0;
  949. }
  950. }
  951. k++;
  952. }
  953. return 1; /* 1: root node ending. */
  954. }
  955. #endif
  956. #ifdef USE_BACKREF_WITH_LEVEL
  957. static int mem_is_in_memp(int mem, int num, UChar* memp)
  958. {
  959. int i;
  960. MemNumType m;
  961. for (i = 0; i < num; i++) {
  962. GET_MEMNUM_INC(m, memp);
  963. if (mem == (int )m) return 1;
  964. }
  965. return 0;
  966. }
  967. static int backref_match_at_nested_level(regex_t* reg
  968. , OnigStackType* top, OnigStackType* stk_base
  969. , int ignore_case, int case_fold_flag
  970. , int nest, int mem_num, UChar* memp, UChar** s, const UChar* send)
  971. {
  972. UChar *ss, *p, *pstart, *pend = NULL_UCHARP;
  973. int level;
  974. OnigStackType* k;
  975. level = 0;
  976. k = top;
  977. k--;
  978. while (k >= stk_base) {
  979. if (k->type == STK_CALL_FRAME) {
  980. level--;
  981. }
  982. else if (k->type == STK_RETURN) {
  983. level++;
  984. }
  985. else if (level == nest) {
  986. if (k->type == STK_MEM_START) {
  987. if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
  988. pstart = k->u.mem.pstr;
  989. if (pend != NULL_UCHARP) {
  990. if (pend - pstart > send - *s) return 0; /* or goto next_mem; */
  991. p = pstart;
  992. ss = *s;
  993. if (ignore_case != 0) {
  994. if (string_cmp_ic(reg->enc, case_fold_flag,
  995. pstart, &ss, (int )(pend - pstart)) == 0)
  996. return 0; /* or goto next_mem; */
  997. }
  998. else {
  999. while (p < pend) {
  1000. if (*p++ != *ss++) return 0; /* or goto next_mem; */
  1001. }
  1002. }
  1003. *s = ss;
  1004. return 1;
  1005. }
  1006. }
  1007. }
  1008. else if (k->type == STK_MEM_END) {
  1009. if (mem_is_in_memp(k->u.mem.num, mem_num, memp)) {
  1010. pend = k->u.mem.pstr;
  1011. }
  1012. }
  1013. }
  1014. k--;
  1015. }
  1016. return 0;
  1017. }
  1018. #endif /* USE_BACKREF_WITH_LEVEL */
  1019. #ifdef ONIG_DEBUG_STATISTICS
  1020. #define USE_TIMEOFDAY
  1021. #ifdef USE_TIMEOFDAY
  1022. #ifdef HAVE_SYS_TIME_H
  1023. #include <sys/time.h>
  1024. #endif
  1025. #ifdef HAVE_UNISTD_H
  1026. #include <unistd.h>
  1027. #endif
  1028. static struct timeval ts, te;
  1029. #define GETTIME(t) gettimeofday(&(t), (struct timezone* )0)
  1030. #define TIMEDIFF(te,ts) (((te).tv_usec - (ts).tv_usec) + \
  1031. (((te).tv_sec - (ts).tv_sec)*1000000))
  1032. #else
  1033. #ifdef HAVE_SYS_TIMES_H
  1034. #include <sys/times.h>
  1035. #endif
  1036. static struct tms ts, te;
  1037. #define GETTIME(t) times(&(t))
  1038. #define TIMEDIFF(te,ts) ((te).tms_utime - (ts).tms_utime)
  1039. #endif
  1040. static int OpCounter[256];
  1041. static int OpPrevCounter[256];
  1042. static unsigned long OpTime[256];
  1043. static int OpCurr = OP_FINISH;
  1044. static int OpPrevTarget = OP_FAIL;
  1045. static int MaxStackDepth = 0;
  1046. #define MOP_IN(opcode) do {\
  1047. if (opcode == OpPrevTarget) OpPrevCounter[OpCurr]++;\
  1048. OpCurr = opcode;\
  1049. OpCounter[opcode]++;\
  1050. GETTIME(ts);\
  1051. } while(0)
  1052. #define MOP_OUT do {\
  1053. GETTIME(te);\
  1054. OpTime[OpCurr] += TIMEDIFF(te, ts);\
  1055. } while(0)
  1056. extern void
  1057. onig_statistics_init(void)
  1058. {
  1059. int i;
  1060. for (i = 0; i < 256; i++) {
  1061. OpCounter[i] = OpPrevCounter[i] = 0; OpTime[i] = 0;
  1062. }
  1063. MaxStackDepth = 0;
  1064. }
  1065. extern void
  1066. onig_print_statistics(FILE* f)
  1067. {
  1068. int i;
  1069. fprintf(f, " count prev time\n");
  1070. for (i = 0; OnigOpInfo[i].opcode >= 0; i++) {
  1071. fprintf(f, "%8d: %8d: %10ld: %s\n",
  1072. OpCounter[i], OpPrevCounter[i], OpTime[i], OnigOpInfo[i].name);
  1073. }
  1074. fprintf(f, "\nmax stack depth: %d\n", MaxStackDepth);
  1075. }
  1076. #define STACK_INC do {\
  1077. stk++;\
  1078. if (stk - stk_base > MaxStackDepth) \
  1079. MaxStackDepth = stk - stk_base;\
  1080. } while(0)
  1081. #else
  1082. #define STACK_INC stk++
  1083. #define MOP_IN(opcode)
  1084. #define MOP_OUT
  1085. #endif
  1086. /* matching region of POSIX API */
  1087. typedef int regoff_t;
  1088. typedef struct {
  1089. regoff_t rm_so;
  1090. regoff_t rm_eo;
  1091. } posix_regmatch_t;
  1092. /* match data(str - end) from position (sstart). */
  1093. /* if sstart == str then set sprev to NULL. */
  1094. static int
  1095. match_at(regex_t* reg, const UChar* str, const UChar* end,
  1096. #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
  1097. const UChar* right_range,
  1098. #endif
  1099. const UChar* sstart, UChar* sprev, OnigMatchArg* msa)
  1100. {
  1101. static UChar FinishCode[] = { OP_FINISH };
  1102. int i, n, num_mem, best_len, pop_level;
  1103. LengthType tlen, tlen2;
  1104. MemNumType mem;
  1105. RelAddrType addr;
  1106. OnigOptionType option = reg->options;
  1107. OnigEncoding encode = reg->enc;
  1108. OnigCaseFoldType case_fold_flag = reg->case_fold_flag;
  1109. UChar *s, *q, *sbegin;
  1110. UChar *p = reg->p;
  1111. char *alloca_base;
  1112. OnigStackType *stk_alloc, *stk_base, *stk, *stk_end;
  1113. OnigStackType *stkp; /* used as any purpose. */
  1114. OnigStackIndex si;
  1115. OnigStackIndex *repeat_stk;
  1116. OnigStackIndex *mem_start_stk, *mem_end_stk;
  1117. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  1118. int scv;
  1119. unsigned char* state_check_buff = msa->state_check_buff;
  1120. int num_comb_exp_check = reg->num_comb_exp_check;
  1121. #endif
  1122. n = reg->num_repeat + reg->num_mem * 2;
  1123. STACK_INIT(alloca_base, n, INIT_MATCH_STACK_SIZE);
  1124. pop_level = reg->stack_pop_level;
  1125. num_mem = reg->num_mem;
  1126. repeat_stk = (OnigStackIndex* )alloca_base;
  1127. mem_start_stk = (OnigStackIndex* )(repeat_stk + reg->num_repeat);
  1128. mem_end_stk = mem_start_stk + num_mem;
  1129. mem_start_stk--; /* for index start from 1,
  1130. mem_start_stk[1]..mem_start_stk[num_mem] */
  1131. mem_end_stk--; /* for index start from 1,
  1132. mem_end_stk[1]..mem_end_stk[num_mem] */
  1133. for (i = 1; i <= num_mem; i++) {
  1134. mem_start_stk[i] = mem_end_stk[i] = INVALID_STACK_INDEX;
  1135. }
  1136. #ifdef ONIG_DEBUG_MATCH
  1137. fprintf(stderr, "match_at: str: %d, end: %d, start: %d, sprev: %d\n",
  1138. (int )str, (int )end, (int )sstart, (int )sprev);
  1139. fprintf(stderr, "size: %d, start offset: %d\n",
  1140. (int )(end - str), (int )(sstart - str));
  1141. #endif
  1142. STACK_PUSH_ENSURED(STK_ALT, FinishCode); /* bottom stack */
  1143. best_len = ONIG_MISMATCH;
  1144. s = (UChar* )sstart;
  1145. while (1) {
  1146. #ifdef ONIG_DEBUG_MATCH
  1147. {
  1148. UChar *q, *bp, buf[50];
  1149. int len;
  1150. fprintf(stderr, "%4d> \"", (int )(s - str));
  1151. bp = buf;
  1152. for (i = 0, q = s; i < 7 && q < end; i++) {
  1153. len = enclen(encode, q);
  1154. while (len-- > 0) *bp++ = *q++;
  1155. }
  1156. if (q < end) { xmemcpy(bp, "...\"", 4); bp += 4; }
  1157. else { xmemcpy(bp, "\"", 1); bp += 1; }
  1158. *bp = 0;
  1159. fputs((char* )buf, stderr);
  1160. for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);
  1161. onig_print_compiled_byte_code(stderr, p, NULL, encode);
  1162. fprintf(stderr, "\n");
  1163. }
  1164. #endif
  1165. sbegin = s;
  1166. switch (*p++) {
  1167. case OP_END: MOP_IN(OP_END);
  1168. n = s - sstart;
  1169. if (n > best_len) {
  1170. OnigRegion* region;
  1171. #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
  1172. if (IS_FIND_LONGEST(option)) {
  1173. if (n > msa->best_len) {
  1174. msa->best_len = n;
  1175. msa->best_s = (UChar* )sstart;
  1176. }
  1177. else
  1178. goto end_best_len;
  1179. }
  1180. #endif
  1181. best_len = n;
  1182. region = msa->region;
  1183. if (region) {
  1184. #ifdef USE_POSIX_API_REGION_OPTION
  1185. if (IS_POSIX_REGION(msa->options)) {
  1186. posix_regmatch_t* rmt = (posix_regmatch_t* )region;
  1187. rmt[0].rm_so = sstart - str;
  1188. rmt[0].rm_eo = s - str;
  1189. for (i = 1; i <= num_mem; i++) {
  1190. if (mem_end_stk[i] != INVALID_STACK_INDEX) {
  1191. if (BIT_STATUS_AT(reg->bt_mem_start, i))
  1192. rmt[i].rm_so = STACK_AT(mem_start_stk[i])->u.mem.pstr - str;
  1193. else
  1194. rmt[i].rm_so = (UChar* )((void* )(mem_start_stk[i])) - str;
  1195. rmt[i].rm_eo = (BIT_STATUS_AT(reg->bt_mem_end, i)
  1196. ? STACK_AT(mem_end_stk[i])->u.mem.pstr
  1197. : (UChar* )((void* )mem_end_stk[i])) - str;
  1198. }
  1199. else {
  1200. rmt[i].rm_so = rmt[i].rm_eo = ONIG_REGION_NOTPOS;
  1201. }
  1202. }
  1203. }
  1204. else {
  1205. #endif /* USE_POSIX_API_REGION_OPTION */
  1206. region->beg[0] = sstart - str;
  1207. region->end[0] = s - str;
  1208. for (i = 1; i <= num_mem; i++) {
  1209. if (mem_end_stk[i] != INVALID_STACK_INDEX) {
  1210. if (BIT_STATUS_AT(reg->bt_mem_start, i))
  1211. region->beg[i] = STACK_AT(mem_start_stk[i])->u.mem.pstr - str;
  1212. else
  1213. region->beg[i] = (UChar* )((void* )mem_start_stk[i]) - str;
  1214. region->end[i] = (BIT_STATUS_AT(reg->bt_mem_end, i)
  1215. ? STACK_AT(mem_end_stk[i])->u.mem.pstr
  1216. : (UChar* )((void* )mem_end_stk[i])) - str;
  1217. }
  1218. else {
  1219. region->beg[i] = region->end[i] = ONIG_REGION_NOTPOS;
  1220. }
  1221. }
  1222. #ifdef USE_CAPTURE_HISTORY
  1223. if (reg->capture_history != 0) {
  1224. int r;
  1225. OnigCaptureTreeNode* node;
  1226. if (IS_NULL(region->history_root)) {
  1227. region->history_root = node = history_node_new();
  1228. CHECK_NULL_RETURN_MEMERR(node);
  1229. }
  1230. else {
  1231. node = region->history_root;
  1232. history_tree_clear(node);
  1233. }
  1234. node->group = 0;
  1235. node->beg = sstart - str;
  1236. node->end = s - str;
  1237. stkp = stk_base;
  1238. r = make_capture_history_tree(region->history_root, &stkp,
  1239. stk, (UChar* )str, reg);
  1240. if (r < 0) {
  1241. best_len = r; /* error code */
  1242. goto finish;
  1243. }
  1244. }
  1245. #endif /* USE_CAPTURE_HISTORY */
  1246. #ifdef USE_POSIX_API_REGION_OPTION
  1247. } /* else IS_POSIX_REGION() */
  1248. #endif
  1249. } /* if (region) */
  1250. } /* n > best_len */
  1251. #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
  1252. end_best_len:
  1253. #endif
  1254. MOP_OUT;
  1255. if (IS_FIND_CONDITION(option)) {
  1256. if (IS_FIND_NOT_EMPTY(option) && s == sstart) {
  1257. best_len = ONIG_MISMATCH;
  1258. goto fail; /* for retry */
  1259. }
  1260. if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {
  1261. goto fail; /* for retry */
  1262. }
  1263. }
  1264. /* default behavior: return first-matching result. */
  1265. goto finish;
  1266. break;
  1267. case OP_EXACT1: MOP_IN(OP_EXACT1);
  1268. DATA_ENSURE(1);
  1269. if (*p != *s) goto fail;
  1270. p++; s++;
  1271. MOP_OUT;
  1272. break;
  1273. case OP_EXACT1_IC: MOP_IN(OP_EXACT1_IC);
  1274. {
  1275. int len;
  1276. UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
  1277. DATA_ENSURE(1);
  1278. len = ONIGENC_MBC_CASE_FOLD(encode,
  1279. /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
  1280. case_fold_flag,
  1281. &s, end, lowbuf);
  1282. DATA_ENSURE(0);
  1283. q = lowbuf;
  1284. while (len-- > 0) {
  1285. if (*p != *q) {
  1286. goto fail;
  1287. }
  1288. p++; q++;
  1289. }
  1290. }
  1291. MOP_OUT;
  1292. break;
  1293. case OP_EXACT2: MOP_IN(OP_EXACT2);
  1294. DATA_ENSURE(2);
  1295. if (*p != *s) goto fail;
  1296. p++; s++;
  1297. if (*p != *s) goto fail;
  1298. sprev = s;
  1299. p++; s++;
  1300. MOP_OUT;
  1301. continue;
  1302. break;
  1303. case OP_EXACT3: MOP_IN(OP_EXACT3);
  1304. DATA_ENSURE(3);
  1305. if (*p != *s) goto fail;
  1306. p++; s++;
  1307. if (*p != *s) goto fail;
  1308. p++; s++;
  1309. if (*p != *s) goto fail;
  1310. sprev = s;
  1311. p++; s++;
  1312. MOP_OUT;
  1313. continue;
  1314. break;
  1315. case OP_EXACT4: MOP_IN(OP_EXACT4);
  1316. DATA_ENSURE(4);
  1317. if (*p != *s) goto fail;
  1318. p++; s++;
  1319. if (*p != *s) goto fail;
  1320. p++; s++;
  1321. if (*p != *s) goto fail;
  1322. p++; s++;
  1323. if (*p != *s) goto fail;
  1324. sprev = s;
  1325. p++; s++;
  1326. MOP_OUT;
  1327. continue;
  1328. break;
  1329. case OP_EXACT5: MOP_IN(OP_EXACT5);
  1330. DATA_ENSURE(5);
  1331. if (*p != *s) goto fail;
  1332. p++; s++;
  1333. if (*p != *s) goto fail;
  1334. p++; s++;
  1335. if (*p != *s) goto fail;
  1336. p++; s++;
  1337. if (*p != *s) goto fail;
  1338. p++; s++;
  1339. if (*p != *s) goto fail;
  1340. sprev = s;
  1341. p++; s++;
  1342. MOP_OUT;
  1343. continue;
  1344. break;
  1345. case OP_EXACTN: MOP_IN(OP_EXACTN);
  1346. GET_LENGTH_INC(tlen, p);
  1347. DATA_ENSURE(tlen);
  1348. while (tlen-- > 0) {
  1349. if (*p++ != *s++) goto fail;
  1350. }
  1351. sprev = s - 1;
  1352. MOP_OUT;
  1353. continue;
  1354. break;
  1355. case OP_EXACTN_IC: MOP_IN(OP_EXACTN_IC);
  1356. {
  1357. int len;
  1358. UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
  1359. GET_LENGTH_INC(tlen, p);
  1360. endp = p + tlen;
  1361. while (p < endp) {
  1362. sprev = s;
  1363. DATA_ENSURE(1);
  1364. len = ONIGENC_MBC_CASE_FOLD(encode,
  1365. /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
  1366. case_fold_flag,
  1367. &s, end, lowbuf);
  1368. DATA_ENSURE(0);
  1369. q = lowbuf;
  1370. while (len-- > 0) {
  1371. if (*p != *q) goto fail;
  1372. p++; q++;
  1373. }
  1374. }
  1375. }
  1376. MOP_OUT;
  1377. continue;
  1378. break;
  1379. case OP_EXACTMB2N1: MOP_IN(OP_EXACTMB2N1);
  1380. DATA_ENSURE(2);
  1381. if (*p != *s) goto fail;
  1382. p++; s++;
  1383. if (*p != *s) goto fail;
  1384. p++; s++;
  1385. MOP_OUT;
  1386. break;
  1387. case OP_EXACTMB2N2: MOP_IN(OP_EXACTMB2N2);
  1388. DATA_ENSURE(4);
  1389. if (*p != *s) goto fail;
  1390. p++; s++;
  1391. if (*p != *s) goto fail;
  1392. p++; s++;
  1393. sprev = s;
  1394. if (*p != *s) goto fail;
  1395. p++; s++;
  1396. if (*p != *s) goto fail;
  1397. p++; s++;
  1398. MOP_OUT;
  1399. continue;
  1400. break;
  1401. case OP_EXACTMB2N3: MOP_IN(OP_EXACTMB2N3);
  1402. DATA_ENSURE(6);
  1403. if (*p != *s) goto fail;
  1404. p++; s++;
  1405. if (*p != *s) goto fail;
  1406. p++; s++;
  1407. if (*p != *s) goto fail;
  1408. p++; s++;
  1409. if (*p != *s) goto fail;
  1410. p++; s++;
  1411. sprev = s;
  1412. if (*p != *s) goto fail;
  1413. p++; s++;
  1414. if (*p != *s) goto fail;
  1415. p++; s++;
  1416. MOP_OUT;
  1417. continue;
  1418. break;
  1419. case OP_EXACTMB2N: MOP_IN(OP_EXACTMB2N);
  1420. GET_LENGTH_INC(tlen, p);
  1421. DATA_ENSURE(tlen * 2);
  1422. while (tlen-- > 0) {
  1423. if (*p != *s) goto fail;
  1424. p++; s++;
  1425. if (*p != *s) goto fail;
  1426. p++; s++;
  1427. }
  1428. sprev = s - 2;
  1429. MOP_OUT;
  1430. continue;
  1431. break;
  1432. case OP_EXACTMB3N: MOP_IN(OP_EXACTMB3N);
  1433. GET_LENGTH_INC(tlen, p);
  1434. DATA_ENSURE(tlen * 3);
  1435. while (tlen-- > 0) {
  1436. if (*p != *s) goto fail;
  1437. p++; s++;
  1438. if (*p != *s) goto fail;
  1439. p++; s++;
  1440. if (*p != *s) goto fail;
  1441. p++; s++;
  1442. }
  1443. sprev = s - 3;
  1444. MOP_OUT;
  1445. continue;
  1446. break;
  1447. case OP_EXACTMBN: MOP_IN(OP_EXACTMBN);
  1448. GET_LENGTH_INC(tlen, p); /* mb-len */
  1449. GET_LENGTH_INC(tlen2, p); /* string len */
  1450. tlen2 *= tlen;
  1451. DATA_ENSURE(tlen2);
  1452. while (tlen2-- > 0) {
  1453. if (*p != *s) goto fail;
  1454. p++; s++;
  1455. }
  1456. sprev = s - tlen;
  1457. MOP_OUT;
  1458. continue;
  1459. break;
  1460. case OP_CCLASS: MOP_IN(OP_CCLASS);
  1461. DATA_ENSURE(1);
  1462. if (BITSET_AT(((BitSetRef )p), *s) == 0) goto fail;
  1463. p += SIZE_BITSET;
  1464. s += enclen(encode, s); /* OP_CCLASS can match mb-code. \D, \S */
  1465. MOP_OUT;
  1466. break;
  1467. case OP_CCLASS_MB: MOP_IN(OP_CCLASS_MB);
  1468. if (! ONIGENC_IS_MBC_HEAD(encode, s)) goto fail;
  1469. cclass_mb:
  1470. GET_LENGTH_INC(tlen, p);
  1471. {
  1472. OnigCodePoint code;
  1473. UChar *ss;
  1474. int mb_len;
  1475. DATA_ENSURE(1);
  1476. mb_len = enclen(encode, s);
  1477. DATA_ENSURE(mb_len);
  1478. ss = s;
  1479. s += mb_len;
  1480. code = ONIGENC_MBC_TO_CODE(encode, ss, s);
  1481. #ifdef PLATFORM_UNALIGNED_WORD_ACCESS
  1482. if (! onig_is_in_code_range(p, code)) goto fail;
  1483. #else
  1484. q = p;
  1485. ALIGNMENT_RIGHT(q);
  1486. if (! onig_is_in_code_range(q, code)) goto fail;
  1487. #endif
  1488. }
  1489. p += tlen;
  1490. MOP_OUT;
  1491. break;
  1492. case OP_CCLASS_MIX: MOP_IN(OP_CCLASS_MIX);
  1493. DATA_ENSURE(1);
  1494. if (ONIGENC_IS_MBC_HEAD(encode, s)) {
  1495. p += SIZE_BITSET;
  1496. goto cclass_mb;
  1497. }
  1498. else {
  1499. if (BITSET_AT(((BitSetRef )p), *s) == 0)
  1500. goto fail;
  1501. p += SIZE_BITSET;
  1502. GET_LENGTH_INC(tlen, p);
  1503. p += tlen;
  1504. s++;
  1505. }
  1506. MOP_OUT;
  1507. break;
  1508. case OP_CCLASS_NOT: MOP_IN(OP_CCLASS_NOT);
  1509. DATA_ENSURE(1);
  1510. if (BITSET_AT(((BitSetRef )p), *s) != 0) goto fail;
  1511. p += SIZE_BITSET;
  1512. s += enclen(encode, s);
  1513. MOP_OUT;
  1514. break;
  1515. case OP_CCLASS_MB_NOT: MOP_IN(OP_CCLASS_MB_NOT);
  1516. DATA_ENSURE(1);
  1517. if (! ONIGENC_IS_MBC_HEAD(encode, s)) {
  1518. s++;
  1519. GET_LENGTH_INC(tlen, p);
  1520. p += tlen;
  1521. goto cc_mb_not_success;
  1522. }
  1523. cclass_mb_not:
  1524. GET_LENGTH_INC(tlen, p);
  1525. {
  1526. OnigCodePoint code;
  1527. UChar *ss;
  1528. int mb_len = enclen(encode, s);
  1529. if (! DATA_ENSURE_CHECK(mb_len)) {
  1530. DATA_ENSURE(1);
  1531. s = (UChar* )end;
  1532. p += tlen;
  1533. goto cc_mb_not_success;
  1534. }
  1535. ss = s;
  1536. s += mb_len;
  1537. code = ONIGENC_MBC_TO_CODE(encode, ss, s);
  1538. #ifdef PLATFORM_UNALIGNED_WORD_ACCESS
  1539. if (onig_is_in_code_range(p, code)) goto fail;
  1540. #else
  1541. q = p;
  1542. ALIGNMENT_RIGHT(q);
  1543. if (onig_is_in_code_range(q, code)) goto fail;
  1544. #endif
  1545. }
  1546. p += tlen;
  1547. cc_mb_not_success:
  1548. MOP_OUT;
  1549. break;
  1550. case OP_CCLASS_MIX_NOT: MOP_IN(OP_CCLASS_MIX_NOT);
  1551. DATA_ENSURE(1);
  1552. if (ONIGENC_IS_MBC_HEAD(encode, s)) {
  1553. p += SIZE_BITSET;
  1554. goto cclass_mb_not;
  1555. }
  1556. else {
  1557. if (BITSET_AT(((BitSetRef )p), *s) != 0)
  1558. goto fail;
  1559. p += SIZE_BITSET;
  1560. GET_LENGTH_INC(tlen, p);
  1561. p += tlen;
  1562. s++;
  1563. }
  1564. MOP_OUT;
  1565. break;
  1566. case OP_CCLASS_NODE: MOP_IN(OP_CCLASS_NODE);
  1567. {
  1568. OnigCodePoint code;
  1569. void *node;
  1570. int mb_len;
  1571. UChar *ss;
  1572. DATA_ENSURE(1);
  1573. GET_POINTER_INC(node, p);
  1574. mb_len = enclen(encode, s);
  1575. ss = s;
  1576. s += mb_len;
  1577. DATA_ENSURE(0);
  1578. code = ONIGENC_MBC_TO_CODE(encode, ss, s);
  1579. if (onig_is_code_in_cc_len(mb_len, code, node) == 0) goto fail;
  1580. }
  1581. MOP_OUT;
  1582. break;
  1583. case OP_ANYCHAR: MOP_IN(OP_ANYCHAR);
  1584. DATA_ENSURE(1);
  1585. n = enclen(encode, s);
  1586. DATA_ENSURE(n);
  1587. if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
  1588. s += n;
  1589. MOP_OUT;
  1590. break;
  1591. case OP_ANYCHAR_ML: MOP_IN(OP_ANYCHAR_ML);
  1592. DATA_ENSURE(1);
  1593. n = enclen(encode, s);
  1594. DATA_ENSURE(n);
  1595. s += n;
  1596. MOP_OUT;
  1597. break;
  1598. case OP_ANYCHAR_STAR: MOP_IN(OP_ANYCHAR_STAR);
  1599. while (DATA_ENSURE_CHECK1) {
  1600. STACK_PUSH_ALT(p, s, sprev);
  1601. n = enclen(encode, s);
  1602. DATA_ENSURE(n);
  1603. if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
  1604. sprev = s;
  1605. s += n;
  1606. }
  1607. MOP_OUT;
  1608. break;
  1609. case OP_ANYCHAR_ML_STAR: MOP_IN(OP_ANYCHAR_ML_STAR);
  1610. while (DATA_ENSURE_CHECK1) {
  1611. STACK_PUSH_ALT(p, s, sprev);
  1612. n = enclen(encode, s);
  1613. if (n > 1) {
  1614. DATA_ENSURE(n);
  1615. sprev = s;
  1616. s += n;
  1617. }
  1618. else {
  1619. sprev = s;
  1620. s++;
  1621. }
  1622. }
  1623. MOP_OUT;
  1624. break;
  1625. case OP_ANYCHAR_STAR_PEEK_NEXT: MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
  1626. while (DATA_ENSURE_CHECK1) {
  1627. if (*p == *s) {
  1628. STACK_PUSH_ALT(p + 1, s, sprev);
  1629. }
  1630. n = enclen(encode, s);
  1631. DATA_ENSURE(n);
  1632. if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
  1633. sprev = s;
  1634. s += n;
  1635. }
  1636. p++;
  1637. MOP_OUT;
  1638. break;
  1639. case OP_ANYCHAR_ML_STAR_PEEK_NEXT:MOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
  1640. while (DATA_ENSURE_CHECK1) {
  1641. if (*p == *s) {
  1642. STACK_PUSH_ALT(p + 1, s, sprev);
  1643. }
  1644. n = enclen(encode, s);
  1645. if (n > 1) {
  1646. DATA_ENSURE(n);
  1647. sprev = s;
  1648. s += n;
  1649. }
  1650. else {
  1651. sprev = s;
  1652. s++;
  1653. }
  1654. }
  1655. p++;
  1656. MOP_OUT;
  1657. break;
  1658. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  1659. case OP_STATE_CHECK_ANYCHAR_STAR: MOP_IN(OP_STATE_CHECK_ANYCHAR_STAR);
  1660. GET_STATE_CHECK_NUM_INC(mem, p);
  1661. while (DATA_ENSURE_CHECK1) {
  1662. STATE_CHECK_VAL(scv, mem);
  1663. if (scv) goto fail;
  1664. STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem);
  1665. n = enclen(encode, s);
  1666. DATA_ENSURE(n);
  1667. if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
  1668. sprev = s;
  1669. s += n;
  1670. }
  1671. MOP_OUT;
  1672. break;
  1673. case OP_STATE_CHECK_ANYCHAR_ML_STAR:
  1674. MOP_IN(OP_STATE_CHECK_ANYCHAR_ML_STAR);
  1675. GET_STATE_CHECK_NUM_INC(mem, p);
  1676. while (DATA_ENSURE_CHECK1) {
  1677. STATE_CHECK_VAL(scv, mem);
  1678. if (scv) goto fail;
  1679. STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem);
  1680. n = enclen(encode, s);
  1681. if (n > 1) {
  1682. DATA_ENSURE(n);
  1683. sprev = s;
  1684. s += n;
  1685. }
  1686. else {
  1687. sprev = s;
  1688. s++;
  1689. }
  1690. }
  1691. MOP_OUT;
  1692. break;
  1693. #endif /* USE_COMBINATION_EXPLOSION_CHECK */
  1694. case OP_WORD: MOP_IN(OP_WORD);
  1695. DATA_ENSURE(1);
  1696. if (! ONIGENC_IS_MBC_WORD(encode, s, end))
  1697. goto fail;
  1698. s += enclen(encode, s);
  1699. MOP_OUT;
  1700. break;
  1701. case OP_NOT_WORD: MOP_IN(OP_NOT_WORD);
  1702. DATA_ENSURE(1);
  1703. if (ONIGENC_IS_MBC_WORD(encode, s, end))
  1704. goto fail;
  1705. s += enclen(encode, s);
  1706. MOP_OUT;
  1707. break;
  1708. case OP_WORD_BOUND: MOP_IN(OP_WORD_BOUND);
  1709. if (ON_STR_BEGIN(s)) {
  1710. DATA_ENSURE(1);
  1711. if (! ONIGENC_IS_MBC_WORD(encode, s, end))
  1712. goto fail;
  1713. }
  1714. else if (ON_STR_END(s)) {
  1715. if (! ONIGENC_IS_MBC_WORD(encode, sprev, end))
  1716. goto fail;
  1717. }
  1718. else {
  1719. if (ONIGENC_IS_MBC_WORD(encode, s, end)
  1720. == ONIGENC_IS_MBC_WORD(encode, sprev, end))
  1721. goto fail;
  1722. }
  1723. MOP_OUT;
  1724. continue;
  1725. break;
  1726. case OP_NOT_WORD_BOUND: MOP_IN(OP_NOT_WORD_BOUND);
  1727. if (ON_STR_BEGIN(s)) {
  1728. if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end))
  1729. goto fail;
  1730. }
  1731. else if (ON_STR_END(s)) {
  1732. if (ONIGENC_IS_MBC_WORD(encode, sprev, end))
  1733. goto fail;
  1734. }
  1735. else {
  1736. if (ONIGENC_IS_MBC_WORD(encode, s, end)
  1737. != ONIGENC_IS_MBC_WORD(encode, sprev, end))
  1738. goto fail;
  1739. }
  1740. MOP_OUT;
  1741. continue;
  1742. break;
  1743. #ifdef USE_WORD_BEGIN_END
  1744. case OP_WORD_BEGIN: MOP_IN(OP_WORD_BEGIN);
  1745. if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end)) {
  1746. if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
  1747. MOP_OUT;
  1748. continue;
  1749. }
  1750. }
  1751. goto fail;
  1752. break;
  1753. case OP_WORD_END: MOP_IN(OP_WORD_END);
  1754. if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
  1755. if (ON_STR_END(s) || !ONIGENC_IS_MBC_WORD(encode, s, end)) {
  1756. MOP_OUT;
  1757. continue;
  1758. }
  1759. }
  1760. goto fail;
  1761. break;
  1762. #endif
  1763. case OP_BEGIN_BUF: MOP_IN(OP_BEGIN_BUF);
  1764. if (! ON_STR_BEGIN(s)) goto fail;
  1765. MOP_OUT;
  1766. continue;
  1767. break;
  1768. case OP_END_BUF: MOP_IN(OP_END_BUF);
  1769. if (! ON_STR_END(s)) goto fail;
  1770. MOP_OUT;
  1771. continue;
  1772. break;
  1773. case OP_BEGIN_LINE: MOP_IN(OP_BEGIN_LINE);
  1774. if (ON_STR_BEGIN(s)) {
  1775. if (IS_NOTBOL(msa->options)) goto fail;
  1776. MOP_OUT;
  1777. continue;
  1778. }
  1779. else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end) && !ON_STR_END(s)) {
  1780. MOP_OUT;
  1781. continue;
  1782. }
  1783. goto fail;
  1784. break;
  1785. case OP_END_LINE: MOP_IN(OP_END_LINE);
  1786. if (ON_STR_END(s)) {
  1787. #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
  1788. if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {
  1789. #endif
  1790. if (IS_NOTEOL(msa->options)) goto fail;
  1791. MOP_OUT;
  1792. continue;
  1793. #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
  1794. }
  1795. #endif
  1796. }
  1797. else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) {
  1798. MOP_OUT;
  1799. continue;
  1800. }
  1801. #ifdef USE_CRNL_AS_LINE_TERMINATOR
  1802. else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {
  1803. MOP_OUT;
  1804. continue;
  1805. }
  1806. #endif
  1807. goto fail;
  1808. break;
  1809. case OP_SEMI_END_BUF: MOP_IN(OP_SEMI_END_BUF);
  1810. if (ON_STR_END(s)) {
  1811. #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
  1812. if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {
  1813. #endif
  1814. if (IS_NOTEOL(msa->options)) goto fail;
  1815. MOP_OUT;
  1816. continue;
  1817. #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
  1818. }
  1819. #endif
  1820. }
  1821. else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end) &&
  1822. ON_STR_END(s + enclen(encode, s))) {
  1823. MOP_OUT;
  1824. continue;
  1825. }
  1826. #ifdef USE_CRNL_AS_LINE_TERMINATOR
  1827. else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {
  1828. UChar* ss = s + enclen(encode, s);
  1829. ss += enclen(encode, ss);
  1830. if (ON_STR_END(ss)) {
  1831. MOP_OUT;
  1832. continue;
  1833. }
  1834. }
  1835. #endif
  1836. goto fail;
  1837. break;
  1838. case OP_BEGIN_POSITION: MOP_IN(OP_BEGIN_POSITION);
  1839. if (s != msa->start)
  1840. goto fail;
  1841. MOP_OUT;
  1842. continue;
  1843. break;
  1844. case OP_MEMORY_START_PUSH: MOP_IN(OP_MEMORY_START_PUSH);
  1845. GET_MEMNUM_INC(mem, p);
  1846. STACK_PUSH_MEM_START(mem, s);
  1847. MOP_OUT;
  1848. continue;
  1849. break;
  1850. case OP_MEMORY_START: MOP_IN(OP_MEMORY_START);
  1851. GET_MEMNUM_INC(mem, p);
  1852. mem_start_stk[mem] = (OnigStackIndex )((void* )s);
  1853. MOP_OUT;
  1854. continue;
  1855. break;
  1856. case OP_MEMORY_END_PUSH: MOP_IN(OP_MEMORY_END_PUSH);
  1857. GET_MEMNUM_INC(mem, p);
  1858. STACK_PUSH_MEM_END(mem, s);
  1859. MOP_OUT;
  1860. continue;
  1861. break;
  1862. case OP_MEMORY_END: MOP_IN(OP_MEMORY_END);
  1863. GET_MEMNUM_INC(mem, p);
  1864. mem_end_stk[mem] = (OnigStackIndex )((void* )s);
  1865. MOP_OUT;
  1866. continue;
  1867. break;
  1868. #ifdef USE_SUBEXP_CALL
  1869. case OP_MEMORY_END_PUSH_REC: MOP_IN(OP_MEMORY_END_PUSH_REC);
  1870. GET_MEMNUM_INC(mem, p);
  1871. STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */
  1872. STACK_PUSH_MEM_END(mem, s);
  1873. mem_start_stk[mem] = GET_STACK_INDEX(stkp);
  1874. MOP_OUT;
  1875. continue;
  1876. break;
  1877. case OP_MEMORY_END_REC: MOP_IN(OP_MEMORY_END_REC);
  1878. GET_MEMNUM_INC(mem, p);
  1879. mem_end_stk[mem] = (OnigStackIndex )((void* )s);
  1880. STACK_GET_MEM_START(mem, stkp);
  1881. if (BIT_STATUS_AT(reg->bt_mem_start, mem))
  1882. mem_start_stk[mem] = GET_STACK_INDEX(stkp);
  1883. else
  1884. mem_start_stk[mem] = (OnigStackIndex )((void* )stkp->u.mem.pstr);
  1885. STACK_PUSH_MEM_END_MARK(mem);
  1886. MOP_OUT;
  1887. continue;
  1888. break;
  1889. #endif
  1890. case OP_BACKREF1: MOP_IN(OP_BACKREF1);
  1891. mem = 1;
  1892. goto backref;
  1893. break;
  1894. case OP_BACKREF2: MOP_IN(OP_BACKREF2);
  1895. mem = 2;
  1896. goto backref;
  1897. break;
  1898. case OP_BACKREFN: MOP_IN(OP_BACKREFN);
  1899. GET_MEMNUM_INC(mem, p);
  1900. backref:
  1901. {
  1902. int len;
  1903. UChar *pstart, *pend;
  1904. /* if you want to remove following line,
  1905. you should check in parse and compile time. */
  1906. if (mem > num_mem) goto fail;
  1907. if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;
  1908. if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;
  1909. if (BIT_STATUS_AT(reg->bt_mem_start, mem))
  1910. pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
  1911. else
  1912. pstart = (UChar* )((void* )mem_start_stk[mem]);
  1913. pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
  1914. ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
  1915. : (UChar* )((void* )mem_end_stk[mem]));
  1916. n = pend - pstart;
  1917. DATA_ENSURE(n);
  1918. sprev = s;
  1919. STRING_CMP(pstart, s, n);
  1920. while (sprev + (len = enclen(encode, sprev)) < s)
  1921. sprev += len;
  1922. MOP_OUT;
  1923. continue;
  1924. }
  1925. break;
  1926. case OP_BACKREFN_IC: MOP_IN(OP_BACKREFN_IC);
  1927. GET_MEMNUM_INC(mem, p);
  1928. {
  1929. int len;
  1930. UChar *pstart, *pend;
  1931. /* if you want to remove following line,
  1932. you should check in parse and compile time. */
  1933. if (mem > num_mem) goto fail;
  1934. if (mem_end_stk[mem] == INVALID_STACK_INDEX) goto fail;
  1935. if (mem_start_stk[mem] == INVALID_STACK_INDEX) goto fail;
  1936. if (BIT_STATUS_AT(reg->bt_mem_start, mem))
  1937. pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
  1938. else
  1939. pstart = (UChar* )((void* )mem_start_stk[mem]);
  1940. pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
  1941. ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
  1942. : (UChar* )((void* )mem_end_stk[mem]));
  1943. n = pend - pstart;
  1944. DATA_ENSURE(n);
  1945. sprev = s;
  1946. STRING_CMP_IC(case_fold_flag, pstart, &s, n);
  1947. while (sprev + (len = enclen(encode, sprev)) < s)
  1948. sprev += len;
  1949. MOP_OUT;
  1950. continue;
  1951. }
  1952. break;
  1953. case OP_BACKREF_MULTI: MOP_IN(OP_BACKREF_MULTI);
  1954. {
  1955. int len, is_fail;
  1956. UChar *pstart, *pend, *swork;
  1957. GET_LENGTH_INC(tlen, p);
  1958. for (i = 0; i < tlen; i++) {
  1959. GET_MEMNUM_INC(mem, p);
  1960. if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;
  1961. if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
  1962. if (BIT_STATUS_AT(reg->bt_mem_start, mem))
  1963. pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
  1964. else
  1965. pstart = (UChar* )((void* )mem_start_stk[mem]);
  1966. pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
  1967. ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
  1968. : (UChar* )((void* )mem_end_stk[mem]));
  1969. n = pend - pstart;
  1970. DATA_ENSURE(n);
  1971. sprev = s;
  1972. swork = s;
  1973. STRING_CMP_VALUE(pstart, swork, n, is_fail);
  1974. if (is_fail) continue;
  1975. s = swork;
  1976. while (sprev + (len = enclen(encode, sprev)) < s)
  1977. sprev += len;
  1978. p += (SIZE_MEMNUM * (tlen - i - 1));
  1979. break; /* success */
  1980. }
  1981. if (i == tlen) goto fail;
  1982. MOP_OUT;
  1983. continue;
  1984. }
  1985. break;
  1986. case OP_BACKREF_MULTI_IC: MOP_IN(OP_BACKREF_MULTI_IC);
  1987. {
  1988. int len, is_fail;
  1989. UChar *pstart, *pend, *swork;
  1990. GET_LENGTH_INC(tlen, p);
  1991. for (i = 0; i < tlen; i++) {
  1992. GET_MEMNUM_INC(mem, p);
  1993. if (mem_end_stk[mem] == INVALID_STACK_INDEX) continue;
  1994. if (mem_start_stk[mem] == INVALID_STACK_INDEX) continue;
  1995. if (BIT_STATUS_AT(reg->bt_mem_start, mem))
  1996. pstart = STACK_AT(mem_start_stk[mem])->u.mem.pstr;
  1997. else
  1998. pstart = (UChar* )((void* )mem_start_stk[mem]);
  1999. pend = (BIT_STATUS_AT(reg->bt_mem_end, mem)
  2000. ? STACK_AT(mem_end_stk[mem])->u.mem.pstr
  2001. : (UChar* )((void* )mem_end_stk[mem]));
  2002. n = pend - pstart;
  2003. DATA_ENSURE(n);
  2004. sprev = s;
  2005. swork = s;
  2006. STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, is_fail);
  2007. if (is_fail) continue;
  2008. s = swork;
  2009. while (sprev + (len = enclen(encode, sprev)) < s)
  2010. sprev += len;
  2011. p += (SIZE_MEMNUM * (tlen - i - 1));
  2012. break; /* success */
  2013. }
  2014. if (i == tlen) goto fail;
  2015. MOP_OUT;
  2016. continue;
  2017. }
  2018. break;
  2019. #ifdef USE_BACKREF_WITH_LEVEL
  2020. case OP_BACKREF_WITH_LEVEL:
  2021. {
  2022. int len;
  2023. OnigOptionType ic;
  2024. LengthType level;
  2025. GET_OPTION_INC(ic, p);
  2026. GET_LENGTH_INC(level, p);
  2027. GET_LENGTH_INC(tlen, p);
  2028. sprev = s;
  2029. if (backref_match_at_nested_level(reg, stk, stk_base, ic
  2030. , case_fold_flag, (int )level, (int )tlen, p, &s, end)) {
  2031. while (sprev + (len = enclen(encode, sprev)) < s)
  2032. sprev += len;
  2033. p += (SIZE_MEMNUM * tlen);
  2034. }
  2035. else
  2036. goto fail;
  2037. MOP_OUT;
  2038. continue;
  2039. }
  2040. break;
  2041. #endif
  2042. #if 0 /* no need: IS_DYNAMIC_OPTION() == 0 */
  2043. case OP_SET_OPTION_PUSH: MOP_IN(OP_SET_OPTION_PUSH);
  2044. GET_OPTION_INC(option, p);
  2045. STACK_PUSH_ALT(p, s, sprev);
  2046. p += SIZE_OP_SET_OPTION + SIZE_OP_FAIL;
  2047. MOP_OUT;
  2048. continue;
  2049. break;
  2050. case OP_SET_OPTION: MOP_IN(OP_SET_OPTION);
  2051. GET_OPTION_INC(option, p);
  2052. MOP_OUT;
  2053. continue;
  2054. break;
  2055. #endif
  2056. case OP_NULL_CHECK_START: MOP_IN(OP_NULL_CHECK_START);
  2057. GET_MEMNUM_INC(mem, p); /* mem: null check id */
  2058. STACK_PUSH_NULL_CHECK_START(mem, s);
  2059. MOP_OUT;
  2060. continue;
  2061. break;
  2062. case OP_NULL_CHECK_END: MOP_IN(OP_NULL_CHECK_END);
  2063. {
  2064. int isnull;
  2065. GET_MEMNUM_INC(mem, p); /* mem: null check id */
  2066. STACK_NULL_CHECK(isnull, mem, s);
  2067. if (isnull) {
  2068. #ifdef ONIG_DEBUG_MATCH
  2069. fprintf(stderr, "NULL_CHECK_END: skip id:%d, s:%d\n",
  2070. (int )mem, (int )s);
  2071. #endif
  2072. null_check_found:
  2073. /* empty loop founded, skip next instruction */
  2074. switch (*p++) {
  2075. case OP_JUMP:
  2076. case OP_PUSH:
  2077. p += SIZE_RELADDR;
  2078. break;
  2079. case OP_REPEAT_INC:
  2080. case OP_REPEAT_INC_NG:
  2081. case OP_REPEAT_INC_SG:
  2082. case OP_REPEAT_INC_NG_SG:
  2083. p += SIZE_MEMNUM;
  2084. break;
  2085. default:
  2086. goto unexpected_bytecode_error;
  2087. break;
  2088. }
  2089. }
  2090. }
  2091. MOP_OUT;
  2092. continue;
  2093. break;
  2094. #ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
  2095. case OP_NULL_CHECK_END_MEMST: MOP_IN(OP_NULL_CHECK_END_MEMST);
  2096. {
  2097. int isnull;
  2098. GET_MEMNUM_INC(mem, p); /* mem: null check id */
  2099. STACK_NULL_CHECK_MEMST(isnull, mem, s, reg);
  2100. if (isnull) {
  2101. #ifdef ONIG_DEBUG_MATCH
  2102. fprintf(stderr, "NULL_CHECK_END_MEMST: skip id:%d, s:%d\n",
  2103. (int )mem, (int )s);
  2104. #endif
  2105. if (isnull == -1) goto fail;
  2106. goto null_check_found;
  2107. }
  2108. }
  2109. MOP_OUT;
  2110. continue;
  2111. break;
  2112. #endif
  2113. #ifdef USE_SUBEXP_CALL
  2114. case OP_NULL_CHECK_END_MEMST_PUSH:
  2115. MOP_IN(OP_NULL_CHECK_END_MEMST_PUSH);
  2116. {
  2117. int isnull;
  2118. GET_MEMNUM_INC(mem, p); /* mem: null check id */
  2119. #ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
  2120. STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);
  2121. #else
  2122. STACK_NULL_CHECK_REC(isnull, mem, s);
  2123. #endif
  2124. if (isnull) {
  2125. #ifdef ONIG_DEBUG_MATCH
  2126. fprintf(stderr, "NULL_CHECK_END_MEMST_PUSH: skip id:%d, s:%d\n",
  2127. (int )mem, (int )s);
  2128. #endif
  2129. if (isnull == -1) goto fail;
  2130. goto null_check_found;
  2131. }
  2132. else {
  2133. STACK_PUSH_NULL_CHECK_END(mem);
  2134. }
  2135. }
  2136. MOP_OUT;
  2137. continue;
  2138. break;
  2139. #endif
  2140. case OP_JUMP: MOP_IN(OP_JUMP);
  2141. GET_RELADDR_INC(addr, p);
  2142. p += addr;
  2143. MOP_OUT;
  2144. CHECK_INTERRUPT_IN_MATCH_AT;
  2145. continue;
  2146. break;
  2147. case OP_PUSH: MOP_IN(OP_PUSH);
  2148. GET_RELADDR_INC(addr, p);
  2149. STACK_PUSH_ALT(p + addr, s, sprev);
  2150. MOP_OUT;
  2151. continue;
  2152. break;
  2153. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  2154. case OP_STATE_CHECK_PUSH: MOP_IN(OP_STATE_CHECK_PUSH);
  2155. GET_STATE_CHECK_NUM_INC(mem, p);
  2156. STATE_CHECK_VAL(scv, mem);
  2157. if (scv) goto fail;
  2158. GET_RELADDR_INC(addr, p);
  2159. STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem);
  2160. MOP_OUT;
  2161. continue;
  2162. break;
  2163. case OP_STATE_CHECK_PUSH_OR_JUMP: MOP_IN(OP_STATE_CHECK_PUSH_OR_JUMP);
  2164. GET_STATE_CHECK_NUM_INC(mem, p);
  2165. GET_RELADDR_INC(addr, p);
  2166. STATE_CHECK_VAL(scv, mem);
  2167. if (scv) {
  2168. p += addr;
  2169. }
  2170. else {
  2171. STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem);
  2172. }
  2173. MOP_OUT;
  2174. continue;
  2175. break;
  2176. case OP_STATE_CHECK: MOP_IN(OP_STATE_CHECK);
  2177. GET_STATE_CHECK_NUM_INC(mem, p);
  2178. STATE_CHECK_VAL(scv, mem);
  2179. if (scv) goto fail;
  2180. STACK_PUSH_STATE_CHECK(s, mem);
  2181. MOP_OUT;
  2182. continue;
  2183. break;
  2184. #endif /* USE_COMBINATION_EXPLOSION_CHECK */
  2185. case OP_POP: MOP_IN(OP_POP);
  2186. STACK_POP_ONE;
  2187. MOP_OUT;
  2188. continue;
  2189. break;
  2190. case OP_PUSH_OR_JUMP_EXACT1: MOP_IN(OP_PUSH_OR_JUMP_EXACT1);
  2191. GET_RELADDR_INC(addr, p);
  2192. if (*p == *s && DATA_ENSURE_CHECK1) {
  2193. p++;
  2194. STACK_PUSH_ALT(p + addr, s, sprev);
  2195. MOP_OUT;
  2196. continue;
  2197. }
  2198. p += (addr + 1);
  2199. MOP_OUT;
  2200. continue;
  2201. break;
  2202. case OP_PUSH_IF_PEEK_NEXT: MOP_IN(OP_PUSH_IF_PEEK_NEXT);
  2203. GET_RELADDR_INC(addr, p);
  2204. if (*p == *s) {
  2205. p++;
  2206. STACK_PUSH_ALT(p + addr, s, sprev);
  2207. MOP_OUT;
  2208. continue;
  2209. }
  2210. p++;
  2211. MOP_OUT;
  2212. continue;
  2213. break;
  2214. case OP_REPEAT: MOP_IN(OP_REPEAT);
  2215. {
  2216. GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
  2217. GET_RELADDR_INC(addr, p);
  2218. STACK_ENSURE(1);
  2219. repeat_stk[mem] = GET_STACK_INDEX(stk);
  2220. STACK_PUSH_REPEAT(mem, p);
  2221. if (reg->repeat_range[mem].lower == 0) {
  2222. STACK_PUSH_ALT(p + addr, s, sprev);
  2223. }
  2224. }
  2225. MOP_OUT;
  2226. continue;
  2227. break;
  2228. case OP_REPEAT_NG: MOP_IN(OP_REPEAT_NG);
  2229. {
  2230. GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
  2231. GET_RELADDR_INC(addr, p);
  2232. STACK_ENSURE(1);
  2233. repeat_stk[mem] = GET_STACK_INDEX(stk);
  2234. STACK_PUSH_REPEAT(mem, p);
  2235. if (reg->repeat_range[mem].lower == 0) {
  2236. STACK_PUSH_ALT(p, s, sprev);
  2237. p += addr;
  2238. }
  2239. }
  2240. MOP_OUT;
  2241. continue;
  2242. break;
  2243. case OP_REPEAT_INC: MOP_IN(OP_REPEAT_INC);
  2244. GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
  2245. si = repeat_stk[mem];
  2246. stkp = STACK_AT(si);
  2247. repeat_inc:
  2248. stkp->u.repeat.count++;
  2249. if (stkp->u.repeat.count >= reg->repeat_range[mem].upper) {
  2250. /* end of repeat. Nothing to do. */
  2251. }
  2252. else if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
  2253. STACK_PUSH_ALT(p, s, sprev);
  2254. p = STACK_AT(si)->u.repeat.pcode; /* Don't use stkp after PUSH. */
  2255. }
  2256. else {
  2257. p = stkp->u.repeat.pcode;
  2258. }
  2259. STACK_PUSH_REPEAT_INC(si);
  2260. MOP_OUT;
  2261. CHECK_INTERRUPT_IN_MATCH_AT;
  2262. continue;
  2263. break;
  2264. case OP_REPEAT_INC_SG: MOP_IN(OP_REPEAT_INC_SG);
  2265. GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
  2266. STACK_GET_REPEAT(mem, stkp);
  2267. si = GET_STACK_INDEX(stkp);
  2268. goto repeat_inc;
  2269. break;
  2270. case OP_REPEAT_INC_NG: MOP_IN(OP_REPEAT_INC_NG);
  2271. GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
  2272. si = repeat_stk[mem];
  2273. stkp = STACK_AT(si);
  2274. repeat_inc_ng:
  2275. stkp->u.repeat.count++;
  2276. if (stkp->u.repeat.count < reg->repeat_range[mem].upper) {
  2277. if (stkp->u.repeat.count >= reg->repeat_range[mem].lower) {
  2278. UChar* pcode = stkp->u.repeat.pcode;
  2279. STACK_PUSH_REPEAT_INC(si);
  2280. STACK_PUSH_ALT(pcode, s, sprev);
  2281. }
  2282. else {
  2283. p = stkp->u.repeat.pcode;
  2284. STACK_PUSH_REPEAT_INC(si);
  2285. }
  2286. }
  2287. else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {
  2288. STACK_PUSH_REPEAT_INC(si);
  2289. }
  2290. MOP_OUT;
  2291. CHECK_INTERRUPT_IN_MATCH_AT;
  2292. continue;
  2293. break;
  2294. case OP_REPEAT_INC_NG_SG: MOP_IN(OP_REPEAT_INC_NG_SG);
  2295. GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
  2296. STACK_GET_REPEAT(mem, stkp);
  2297. si = GET_STACK_INDEX(stkp);
  2298. goto repeat_inc_ng;
  2299. break;
  2300. case OP_PUSH_POS: MOP_IN(OP_PUSH_POS);
  2301. STACK_PUSH_POS(s, sprev);
  2302. MOP_OUT;
  2303. continue;
  2304. break;
  2305. case OP_POP_POS: MOP_IN(OP_POP_POS);
  2306. {
  2307. STACK_POS_END(stkp);
  2308. s = stkp->u.state.pstr;
  2309. sprev = stkp->u.state.pstr_prev;
  2310. }
  2311. MOP_OUT;
  2312. continue;
  2313. break;
  2314. case OP_PUSH_POS_NOT: MOP_IN(OP_PUSH_POS_NOT);
  2315. GET_RELADDR_INC(addr, p);
  2316. STACK_PUSH_POS_NOT(p + addr, s, sprev);
  2317. MOP_OUT;
  2318. continue;
  2319. break;
  2320. case OP_FAIL_POS: MOP_IN(OP_FAIL_POS);
  2321. STACK_POP_TIL_POS_NOT;
  2322. goto fail;
  2323. break;
  2324. case OP_PUSH_STOP_BT: MOP_IN(OP_PUSH_STOP_BT);
  2325. STACK_PUSH_STOP_BT;
  2326. MOP_OUT;
  2327. continue;
  2328. break;
  2329. case OP_POP_STOP_BT: MOP_IN(OP_POP_STOP_BT);
  2330. STACK_STOP_BT_END;
  2331. MOP_OUT;
  2332. continue;
  2333. break;
  2334. case OP_LOOK_BEHIND: MOP_IN(OP_LOOK_BEHIND);
  2335. GET_LENGTH_INC(tlen, p);
  2336. s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);
  2337. if (IS_NULL(s)) goto fail;
  2338. sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);
  2339. MOP_OUT;
  2340. continue;
  2341. break;
  2342. case OP_PUSH_LOOK_BEHIND_NOT: MOP_IN(OP_PUSH_LOOK_BEHIND_NOT);
  2343. GET_RELADDR_INC(addr, p);
  2344. GET_LENGTH_INC(tlen, p);
  2345. q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);
  2346. if (IS_NULL(q)) {
  2347. /* too short case -> success. ex. /(?<!XXX)a/.match("a")
  2348. If you want to change to fail, replace following line. */
  2349. p += addr;
  2350. /* goto fail; */
  2351. }
  2352. else {
  2353. STACK_PUSH_LOOK_BEHIND_NOT(p + addr, s, sprev);
  2354. s = q;
  2355. sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);
  2356. }
  2357. MOP_OUT;
  2358. continue;
  2359. break;
  2360. case OP_FAIL_LOOK_BEHIND_NOT: MOP_IN(OP_FAIL_LOOK_BEHIND_NOT);
  2361. STACK_POP_TIL_LOOK_BEHIND_NOT;
  2362. goto fail;
  2363. break;
  2364. #ifdef USE_SUBEXP_CALL
  2365. case OP_CALL: MOP_IN(OP_CALL);
  2366. GET_ABSADDR_INC(addr, p);
  2367. STACK_PUSH_CALL_FRAME(p);
  2368. p = reg->p + addr;
  2369. MOP_OUT;
  2370. continue;
  2371. break;
  2372. case OP_RETURN: MOP_IN(OP_RETURN);
  2373. STACK_RETURN(p);
  2374. STACK_PUSH_RETURN;
  2375. MOP_OUT;
  2376. continue;
  2377. break;
  2378. #endif
  2379. case OP_FINISH:
  2380. goto finish;
  2381. break;
  2382. fail:
  2383. MOP_OUT;
  2384. /* fall */
  2385. case OP_FAIL: MOP_IN(OP_FAIL);
  2386. STACK_POP;
  2387. p = stk->u.state.pcode;
  2388. s = stk->u.state.pstr;
  2389. sprev = stk->u.state.pstr_prev;
  2390. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  2391. if (stk->u.state.state_check != 0) {
  2392. stk->type = STK_STATE_CHECK_MARK;
  2393. stk++;
  2394. }
  2395. #endif
  2396. MOP_OUT;
  2397. continue;
  2398. break;
  2399. default:
  2400. goto bytecode_error;
  2401. } /* end of switch */
  2402. sprev = sbegin;
  2403. } /* end of while(1) */
  2404. finish:
  2405. STACK_SAVE;
  2406. return best_len;
  2407. #ifdef ONIG_DEBUG
  2408. stack_error:
  2409. STACK_SAVE;
  2410. return ONIGERR_STACK_BUG;
  2411. #endif
  2412. bytecode_error:
  2413. STACK_SAVE;
  2414. return ONIGERR_UNDEFINED_BYTECODE;
  2415. unexpected_bytecode_error:
  2416. STACK_SAVE;
  2417. return ONIGERR_UNEXPECTED_BYTECODE;
  2418. }
  2419. static UChar*
  2420. slow_search(OnigEncoding enc, UChar* target, UChar* target_end,
  2421. const UChar* text, const UChar* text_end, UChar* text_range)
  2422. {
  2423. UChar *t, *p, *s, *end;
  2424. end = (UChar* )text_end;
  2425. end -= target_end - target - 1;
  2426. if (end > text_range)
  2427. end = text_range;
  2428. s = (UChar* )text;
  2429. while (s < end) {
  2430. if (*s == *target) {
  2431. p = s + 1;
  2432. t = target + 1;
  2433. while (t < target_end) {
  2434. if (*t != *p++)
  2435. break;
  2436. t++;
  2437. }
  2438. if (t == target_end)
  2439. return s;
  2440. }
  2441. s += enclen(enc, s);
  2442. }
  2443. return (UChar* )NULL;
  2444. }
  2445. static int
  2446. str_lower_case_match(OnigEncoding enc, int case_fold_flag,
  2447. const UChar* t, const UChar* tend,
  2448. const UChar* p, const UChar* end)
  2449. {
  2450. int lowlen;
  2451. UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
  2452. while (t < tend) {
  2453. lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf);
  2454. q = lowbuf;
  2455. while (lowlen > 0) {
  2456. if (*t++ != *q++) return 0;
  2457. lowlen--;
  2458. }
  2459. }
  2460. return 1;
  2461. }
  2462. static UChar*
  2463. slow_search_ic(OnigEncoding enc, int case_fold_flag,
  2464. UChar* target, UChar* target_end,
  2465. const UChar* text, const UChar* text_end, UChar* text_range)
  2466. {
  2467. UChar *s, *end;
  2468. end = (UChar* )text_end;
  2469. end -= target_end - target - 1;
  2470. if (end > text_range)
  2471. end = text_range;
  2472. s = (UChar* )text;
  2473. while (s < end) {
  2474. if (str_lower_case_match(enc, case_fold_flag, target, target_end,
  2475. s, text_end))
  2476. return s;
  2477. s += enclen(enc, s);
  2478. }
  2479. return (UChar* )NULL;
  2480. }
  2481. static UChar*
  2482. slow_search_backward(OnigEncoding enc, UChar* target, UChar* target_end,
  2483. const UChar* text, const UChar* adjust_text,
  2484. const UChar* text_end, const UChar* text_start)
  2485. {
  2486. UChar *t, *p, *s;
  2487. s = (UChar* )text_end;
  2488. s -= (target_end - target);
  2489. if (s > text_start)
  2490. s = (UChar* )text_start;
  2491. else
  2492. s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s);
  2493. while (s >= text) {
  2494. if (*s == *target) {
  2495. p = s + 1;
  2496. t = target + 1;
  2497. while (t < target_end) {
  2498. if (*t != *p++)
  2499. break;
  2500. t++;
  2501. }
  2502. if (t == target_end)
  2503. return s;
  2504. }
  2505. s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s);
  2506. }
  2507. return (UChar* )NULL;
  2508. }
  2509. static UChar*
  2510. slow_search_backward_ic(OnigEncoding enc, int case_fold_flag,
  2511. UChar* target, UChar* target_end,
  2512. const UChar* text, const UChar* adjust_text,
  2513. const UChar* text_end, const UChar* text_start)
  2514. {
  2515. UChar *s;
  2516. s = (UChar* )text_end;
  2517. s -= (target_end - target);
  2518. if (s > text_start)
  2519. s = (UChar* )text_start;
  2520. else
  2521. s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s);
  2522. while (s >= text) {
  2523. if (str_lower_case_match(enc, case_fold_flag,
  2524. target, target_end, s, text_end))
  2525. return s;
  2526. s = (UChar* )onigenc_get_prev_char_head(enc, adjust_text, s);
  2527. }
  2528. return (UChar* )NULL;
  2529. }
  2530. static UChar*
  2531. bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
  2532. const UChar* text, const UChar* text_end,
  2533. const UChar* text_range)
  2534. {
  2535. const UChar *s, *se, *t, *p, *end;
  2536. const UChar *tail;
  2537. int skip, tlen1;
  2538. #ifdef ONIG_DEBUG_SEARCH
  2539. fprintf(stderr, "bm_search_notrev: text: %d, text_end: %d, text_range: %d\n",
  2540. (int )text, (int )text_end, (int )text_range);
  2541. #endif
  2542. tail = target_end - 1;
  2543. tlen1 = tail - target;
  2544. end = text_range;
  2545. if (end + tlen1 > text_end)
  2546. end = text_end - tlen1;
  2547. s = text;
  2548. if (IS_NULL(reg->int_map)) {
  2549. while (s < end) {
  2550. p = se = s + tlen1;
  2551. t = tail;
  2552. while (*p == *t) {
  2553. if (t == target) return (UChar* )s;
  2554. p--; t--;
  2555. }
  2556. skip = reg->map[*se];
  2557. t = s;
  2558. do {
  2559. s += enclen(reg->enc, s);
  2560. } while ((s - t) < skip && s < end);
  2561. }
  2562. }
  2563. else {
  2564. while (s < end) {
  2565. p = se = s + tlen1;
  2566. t = tail;
  2567. while (*p == *t) {
  2568. if (t == target) return (UChar* )s;
  2569. p--; t--;
  2570. }
  2571. skip = reg->int_map[*se];
  2572. t = s;
  2573. do {
  2574. s += enclen(reg->enc, s);
  2575. } while ((s - t) < skip && s < end);
  2576. }
  2577. }
  2578. return (UChar* )NULL;
  2579. }
  2580. static UChar*
  2581. bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
  2582. const UChar* text, const UChar* text_end, const UChar* text_range)
  2583. {
  2584. const UChar *s, *t, *p, *end;
  2585. const UChar *tail;
  2586. end = text_range + (target_end - target) - 1;
  2587. if (end > text_end)
  2588. end = text_end;
  2589. tail = target_end - 1;
  2590. s = text + (target_end - target) - 1;
  2591. if (IS_NULL(reg->int_map)) {
  2592. while (s < end) {
  2593. p = s;
  2594. t = tail;
  2595. while (*p == *t) {
  2596. if (t == target) return (UChar* )p;
  2597. p--; t--;
  2598. }
  2599. s += reg->map[*s];
  2600. }
  2601. }
  2602. else { /* see int_map[] */
  2603. while (s < end) {
  2604. p = s;
  2605. t = tail;
  2606. while (*p == *t) {
  2607. if (t == target) return (UChar* )p;
  2608. p--; t--;
  2609. }
  2610. s += reg->int_map[*s];
  2611. }
  2612. }
  2613. return (UChar* )NULL;
  2614. }
  2615. static int
  2616. set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED,
  2617. int** skip)
  2618. {
  2619. int i, len;
  2620. if (IS_NULL(*skip)) {
  2621. *skip = (int* )xmalloc(sizeof(int) * ONIG_CHAR_TABLE_SIZE);
  2622. if (IS_NULL(*skip)) return ONIGERR_MEMORY;
  2623. }
  2624. len = end - s;
  2625. for (i = 0; i < ONIG_CHAR_TABLE_SIZE; i++)
  2626. (*skip)[i] = len;
  2627. for (i = len - 1; i > 0; i--)
  2628. (*skip)[s[i]] = i;
  2629. return 0;
  2630. }
  2631. static UChar*
  2632. bm_search_backward(regex_t* reg, const UChar* target, const UChar* target_end,
  2633. const UChar* text, const UChar* adjust_text,
  2634. const UChar* text_end, const UChar* text_start)
  2635. {
  2636. const UChar *s, *t, *p;
  2637. s = text_end - (target_end - target);
  2638. if (text_start < s)
  2639. s = text_start;
  2640. else
  2641. s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s);
  2642. while (s >= text) {
  2643. p = s;
  2644. t = target;
  2645. while (t < target_end && *p == *t) {
  2646. p++; t++;
  2647. }
  2648. if (t == target_end)
  2649. return (UChar* )s;
  2650. s -= reg->int_map_backward[*s];
  2651. s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, adjust_text, s);
  2652. }
  2653. return (UChar* )NULL;
  2654. }
  2655. static UChar*
  2656. map_search(OnigEncoding enc, UChar map[],
  2657. const UChar* text, const UChar* text_range)
  2658. {
  2659. const UChar *s = text;
  2660. while (s < text_range) {
  2661. if (map[*s]) return (UChar* )s;
  2662. s += enclen(enc, s);
  2663. }
  2664. return (UChar* )NULL;
  2665. }
  2666. static UChar*
  2667. map_search_backward(OnigEncoding enc, UChar map[],
  2668. const UChar* text, const UChar* adjust_text,
  2669. const UChar* text_start)
  2670. {
  2671. const UChar *s = text_start;
  2672. while (s >= text) {
  2673. if (map[*s]) return (UChar* )s;
  2674. s = onigenc_get_prev_char_head(enc, adjust_text, s);
  2675. }
  2676. return (UChar* )NULL;
  2677. }
  2678. extern int
  2679. onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, OnigRegion* region,
  2680. OnigOptionType option)
  2681. {
  2682. int r;
  2683. UChar *prev;
  2684. OnigMatchArg msa;
  2685. #if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
  2686. start:
  2687. THREAD_ATOMIC_START;
  2688. if (ONIG_STATE(reg) >= ONIG_STATE_NORMAL) {
  2689. ONIG_STATE_INC(reg);
  2690. if (IS_NOT_NULL(reg->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {
  2691. onig_chain_reduce(reg);
  2692. ONIG_STATE_INC(reg);
  2693. }
  2694. }
  2695. else {
  2696. int n;
  2697. THREAD_ATOMIC_END;
  2698. n = 0;
  2699. while (ONIG_STATE(reg) < ONIG_STATE_NORMAL) {
  2700. if (++n > THREAD_PASS_LIMIT_COUNT)
  2701. return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;
  2702. THREAD_PASS;
  2703. }
  2704. goto start;
  2705. }
  2706. THREAD_ATOMIC_END;
  2707. #endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
  2708. MATCH_ARG_INIT(msa, option, region, at);
  2709. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  2710. {
  2711. int offset = at - str;
  2712. STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);
  2713. }
  2714. #endif
  2715. if (region
  2716. #ifdef USE_POSIX_API_REGION_OPTION
  2717. && !IS_POSIX_REGION(option)
  2718. #endif
  2719. ) {
  2720. r = onig_region_resize_clear(region, reg->num_mem + 1);
  2721. }
  2722. else
  2723. r = 0;
  2724. if (r == 0) {
  2725. prev = (UChar* )onigenc_get_prev_char_head(reg->enc, str, at);
  2726. r = match_at(reg, str, end,
  2727. #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
  2728. end,
  2729. #endif
  2730. at, prev, &msa);
  2731. }
  2732. MATCH_ARG_FREE(msa);
  2733. ONIG_STATE_DEC_THREAD(reg);
  2734. return r;
  2735. }
  2736. static int
  2737. forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
  2738. UChar* range, UChar** low, UChar** high, UChar** low_prev)
  2739. {
  2740. UChar *p, *pprev = (UChar* )NULL;
  2741. #ifdef ONIG_DEBUG_SEARCH
  2742. fprintf(stderr, "forward_search_range: str: %d, end: %d, s: %d, range: %d\n",
  2743. (int )str, (int )end, (int )s, (int )range);
  2744. #endif
  2745. p = s;
  2746. if (reg->dmin > 0) {
  2747. if (ONIGENC_IS_SINGLEBYTE(reg->enc)) {
  2748. p += reg->dmin;
  2749. }
  2750. else {
  2751. UChar *q = p + reg->dmin;
  2752. if (q >= end) return 0; /* fail */
  2753. while (p < q) p += enclen(reg->enc, p);
  2754. }
  2755. }
  2756. retry:
  2757. switch (reg->optimize) {
  2758. case ONIG_OPTIMIZE_EXACT:
  2759. p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);
  2760. break;
  2761. case ONIG_OPTIMIZE_EXACT_IC:
  2762. p = slow_search_ic(reg->enc, reg->case_fold_flag,
  2763. reg->exact, reg->exact_end, p, end, range);
  2764. break;
  2765. case ONIG_OPTIMIZE_EXACT_BM:
  2766. p = bm_search(reg, reg->exact, reg->exact_end, p, end, range);
  2767. break;
  2768. case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:
  2769. p = bm_search_notrev(reg, reg->exact, reg->exact_end, p, end, range);
  2770. break;
  2771. case ONIG_OPTIMIZE_MAP:
  2772. p = map_search(reg->enc, reg->map, p, range);
  2773. break;
  2774. }
  2775. if (p && p < range) {
  2776. if (p - reg->dmin < s) {
  2777. retry_gate:
  2778. pprev = p;
  2779. p += enclen(reg->enc, p);
  2780. goto retry;
  2781. }
  2782. if (reg->sub_anchor) {
  2783. UChar* prev;
  2784. switch (reg->sub_anchor) {
  2785. case ANCHOR_BEGIN_LINE:
  2786. if (!ON_STR_BEGIN(p)) {
  2787. prev = onigenc_get_prev_char_head(reg->enc,
  2788. (pprev ? pprev : str), p);
  2789. if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))
  2790. goto retry_gate;
  2791. }
  2792. break;
  2793. case ANCHOR_END_LINE:
  2794. if (ON_STR_END(p)) {
  2795. #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
  2796. prev = (UChar* )onigenc_get_prev_char_head(reg->enc,
  2797. (pprev ? pprev : str), p);
  2798. if (prev && ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))
  2799. goto retry_gate;
  2800. #endif
  2801. }
  2802. else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)
  2803. #ifdef USE_CRNL_AS_LINE_TERMINATOR
  2804. && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)
  2805. #endif
  2806. )
  2807. goto retry_gate;
  2808. break;
  2809. }
  2810. }
  2811. if (reg->dmax == 0) {
  2812. *low = p;
  2813. if (low_prev) {
  2814. if (*low > s)
  2815. *low_prev = onigenc_get_prev_char_head(reg->enc, s, p);
  2816. else
  2817. *low_prev = onigenc_get_prev_char_head(reg->enc,
  2818. (pprev ? pprev : str), p);
  2819. }
  2820. }
  2821. else {
  2822. if (reg->dmax != ONIG_INFINITE_DISTANCE) {
  2823. *low = p - reg->dmax;
  2824. if (p - str < reg->dmax) {
  2825. *low = (UChar* )str;
  2826. if (low_prev)
  2827. *low_prev = onigenc_get_prev_char_head(reg->enc, str, *low);
  2828. }
  2829. else {
  2830. if (*low > s) {
  2831. *low = onigenc_get_right_adjust_char_head_with_prev(reg->enc, s,
  2832. *low, (const UChar** )low_prev);
  2833. if (low_prev && IS_NULL(*low_prev))
  2834. *low_prev = onigenc_get_prev_char_head(reg->enc,
  2835. (pprev ? pprev : s), *low);
  2836. }
  2837. else {
  2838. if (low_prev)
  2839. *low_prev = onigenc_get_prev_char_head(reg->enc,
  2840. (pprev ? pprev : str), *low);
  2841. }
  2842. }
  2843. }
  2844. }
  2845. /* no needs to adjust *high, *high is used as range check only */
  2846. *high = p - reg->dmin;
  2847. #ifdef ONIG_DEBUG_SEARCH
  2848. fprintf(stderr,
  2849. "forward_search_range success: low: %d, high: %d, dmin: %d, dmax: %d\n",
  2850. (int )(*low - str), (int )(*high - str), reg->dmin, reg->dmax);
  2851. #endif
  2852. return 1; /* success */
  2853. }
  2854. return 0; /* fail */
  2855. }
  2856. static int set_bm_backward_skip P_((UChar* s, UChar* end, OnigEncoding enc,
  2857. int** skip));
  2858. #define BM_BACKWARD_SEARCH_LENGTH_THRESHOLD 100
  2859. static int
  2860. backward_search_range(regex_t* reg, const UChar* str, const UChar* end,
  2861. UChar* s, const UChar* range, UChar* adjrange,
  2862. UChar** low, UChar** high)
  2863. {
  2864. int r;
  2865. UChar *p;
  2866. range += reg->dmin;
  2867. p = s;
  2868. retry:
  2869. switch (reg->optimize) {
  2870. case ONIG_OPTIMIZE_EXACT:
  2871. exact_method:
  2872. p = slow_search_backward(reg->enc, reg->exact, reg->exact_end,
  2873. range, adjrange, end, p);
  2874. break;
  2875. case ONIG_OPTIMIZE_EXACT_IC:
  2876. p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,
  2877. reg->exact, reg->exact_end,
  2878. range, adjrange, end, p);
  2879. break;
  2880. case ONIG_OPTIMIZE_EXACT_BM:
  2881. case ONIG_OPTIMIZE_EXACT_BM_NOT_REV:
  2882. if (IS_NULL(reg->int_map_backward)) {
  2883. if (s - range < BM_BACKWARD_SEARCH_LENGTH_THRESHOLD)
  2884. goto exact_method;
  2885. r = set_bm_backward_skip(reg->exact, reg->exact_end, reg->enc,
  2886. &(reg->int_map_backward));
  2887. if (r) return r;
  2888. }
  2889. p = bm_search_backward(reg, reg->exact, reg->exact_end, range, adjrange,
  2890. end, p);
  2891. break;
  2892. case ONIG_OPTIMIZE_MAP:
  2893. p = map_search_backward(reg->enc, reg->map, range, adjrange, p);
  2894. break;
  2895. }
  2896. if (p) {
  2897. if (reg->sub_anchor) {
  2898. UChar* prev;
  2899. switch (reg->sub_anchor) {
  2900. case ANCHOR_BEGIN_LINE:
  2901. if (!ON_STR_BEGIN(p)) {
  2902. prev = onigenc_get_prev_char_head(reg->enc, str, p);
  2903. if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {
  2904. p = prev;
  2905. goto retry;
  2906. }
  2907. }
  2908. break;
  2909. case ANCHOR_END_LINE:
  2910. if (ON_STR_END(p)) {
  2911. #ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
  2912. prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);
  2913. if (IS_NULL(prev)) goto fail;
  2914. if (ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {
  2915. p = prev;
  2916. goto retry;
  2917. }
  2918. #endif
  2919. }
  2920. else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)
  2921. #ifdef USE_CRNL_AS_LINE_TERMINATOR
  2922. && ! ONIGENC_IS_MBC_CRNL(reg->enc, p, end)
  2923. #endif
  2924. ) {
  2925. p = onigenc_get_prev_char_head(reg->enc, adjrange, p);
  2926. if (IS_NULL(p)) goto fail;
  2927. goto retry;
  2928. }
  2929. break;
  2930. }
  2931. }
  2932. /* no needs to adjust *high, *high is used as range check only */
  2933. if (reg->dmax != ONIG_INFINITE_DISTANCE) {
  2934. *low = p - reg->dmax;
  2935. *high = p - reg->dmin;
  2936. *high = onigenc_get_right_adjust_char_head(reg->enc, adjrange, *high);
  2937. }
  2938. #ifdef ONIG_DEBUG_SEARCH
  2939. fprintf(stderr, "backward_search_range: low: %d, high: %d\n",
  2940. (int )(*low - str), (int )(*high - str));
  2941. #endif
  2942. return 1; /* success */
  2943. }
  2944. fail:
  2945. #ifdef ONIG_DEBUG_SEARCH
  2946. fprintf(stderr, "backward_search_range: fail.\n");
  2947. #endif
  2948. return 0; /* fail */
  2949. }
  2950. extern int
  2951. onig_search(regex_t* reg, const UChar* str, const UChar* end,
  2952. const UChar* start, const UChar* range, OnigRegion* region, OnigOptionType option)
  2953. {
  2954. int r;
  2955. UChar *s, *prev;
  2956. OnigMatchArg msa;
  2957. const UChar *orig_start = start;
  2958. #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
  2959. const UChar *orig_range = range;
  2960. #endif
  2961. #if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
  2962. start:
  2963. THREAD_ATOMIC_START;
  2964. if (ONIG_STATE(reg) >= ONIG_STATE_NORMAL) {
  2965. ONIG_STATE_INC(reg);
  2966. if (IS_NOT_NULL(reg->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {
  2967. onig_chain_reduce(reg);
  2968. ONIG_STATE_INC(reg);
  2969. }
  2970. }
  2971. else {
  2972. int n;
  2973. THREAD_ATOMIC_END;
  2974. n = 0;
  2975. while (ONIG_STATE(reg) < ONIG_STATE_NORMAL) {
  2976. if (++n > THREAD_PASS_LIMIT_COUNT)
  2977. return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;
  2978. THREAD_PASS;
  2979. }
  2980. goto start;
  2981. }
  2982. THREAD_ATOMIC_END;
  2983. #endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
  2984. #ifdef ONIG_DEBUG_SEARCH
  2985. fprintf(stderr,
  2986. "onig_search (entry point): str: %d, end: %d, start: %d, range: %d\n",
  2987. (int )str, (int )(end - str), (int )(start - str), (int )(range - str));
  2988. #endif
  2989. if (region
  2990. #ifdef USE_POSIX_API_REGION_OPTION
  2991. && !IS_POSIX_REGION(option)
  2992. #endif
  2993. ) {
  2994. r = onig_region_resize_clear(region, reg->num_mem + 1);
  2995. if (r) goto finish_no_msa;
  2996. }
  2997. if (start > end || start < str) goto mismatch_no_msa;
  2998. #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
  2999. #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
  3000. #define MATCH_AND_RETURN_CHECK(upper_range) \
  3001. r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
  3002. if (r != ONIG_MISMATCH) {\
  3003. if (r >= 0) {\
  3004. if (! IS_FIND_LONGEST(reg->options)) {\
  3005. goto match;\
  3006. }\
  3007. }\
  3008. else goto finish; /* error */ \
  3009. }
  3010. #else
  3011. #define MATCH_AND_RETURN_CHECK(upper_range) \
  3012. r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
  3013. if (r != ONIG_MISMATCH) {\
  3014. if (r >= 0) {\
  3015. goto match;\
  3016. }\
  3017. else goto finish; /* error */ \
  3018. }
  3019. #endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */
  3020. #else
  3021. #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
  3022. #define MATCH_AND_RETURN_CHECK(none) \
  3023. r = match_at(reg, str, end, s, prev, &msa);\
  3024. if (r != ONIG_MISMATCH) {\
  3025. if (r >= 0) {\
  3026. if (! IS_FIND_LONGEST(reg->options)) {\
  3027. goto match;\
  3028. }\
  3029. }\
  3030. else goto finish; /* error */ \
  3031. }
  3032. #else
  3033. #define MATCH_AND_RETURN_CHECK(none) \
  3034. r = match_at(reg, str, end, s, prev, &msa);\
  3035. if (r != ONIG_MISMATCH) {\
  3036. if (r >= 0) {\
  3037. goto match;\
  3038. }\
  3039. else goto finish; /* error */ \
  3040. }
  3041. #endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */
  3042. #endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
  3043. /* anchor optimize: resume search range */
  3044. if (reg->anchor != 0 && str < end) {
  3045. UChar *min_semi_end, *max_semi_end;
  3046. if (reg->anchor & ANCHOR_BEGIN_POSITION) {
  3047. /* search start-position only */
  3048. begin_position:
  3049. if (range > start)
  3050. range = start + 1;
  3051. else
  3052. range = start;
  3053. }
  3054. else if (reg->anchor & ANCHOR_BEGIN_BUF) {
  3055. /* search str-position only */
  3056. if (range > start) {
  3057. if (start != str) goto mismatch_no_msa;
  3058. range = str + 1;
  3059. }
  3060. else {
  3061. if (range <= str) {
  3062. start = str;
  3063. range = str;
  3064. }
  3065. else
  3066. goto mismatch_no_msa;
  3067. }
  3068. }
  3069. else if (reg->anchor & ANCHOR_END_BUF) {
  3070. min_semi_end = max_semi_end = (UChar* )end;
  3071. end_buf:
  3072. if ((OnigDistance )(max_semi_end - str) < reg->anchor_dmin)
  3073. goto mismatch_no_msa;
  3074. if (range > start) {
  3075. if ((OnigDistance )(min_semi_end - start) > reg->anchor_dmax) {
  3076. start = min_semi_end - reg->anchor_dmax;
  3077. if (start < end)
  3078. start = onigenc_get_right_adjust_char_head(reg->enc, str, start);
  3079. else { /* match with empty at end */
  3080. start = onigenc_get_prev_char_head(reg->enc, str, end);
  3081. }
  3082. }
  3083. if ((OnigDistance )(max_semi_end - (range - 1)) < reg->anchor_dmin) {
  3084. range = max_semi_end - reg->anchor_dmin + 1;
  3085. }
  3086. if (start >= range) goto mismatch_no_msa;
  3087. }
  3088. else {
  3089. if ((OnigDistance )(min_semi_end - range) > reg->anchor_dmax) {
  3090. range = min_semi_end - reg->anchor_dmax;
  3091. }
  3092. if ((OnigDistance )(max_semi_end - start) < reg->anchor_dmin) {
  3093. start = max_semi_end - reg->anchor_dmin;
  3094. start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, start);
  3095. }
  3096. if (range > start) goto mismatch_no_msa;
  3097. }
  3098. }
  3099. else if (reg->anchor & ANCHOR_SEMI_END_BUF) {
  3100. UChar* pre_end = ONIGENC_STEP_BACK(reg->enc, str, end, 1);
  3101. max_semi_end = (UChar* )end;
  3102. if (ONIGENC_IS_MBC_NEWLINE(reg->enc, pre_end, end)) {
  3103. min_semi_end = pre_end;
  3104. #ifdef USE_CRNL_AS_LINE_TERMINATOR
  3105. pre_end = ONIGENC_STEP_BACK(reg->enc, str, pre_end, 1);
  3106. if (IS_NOT_NULL(pre_end) &&
  3107. ONIGENC_IS_MBC_CRNL(reg->enc, pre_end, end)) {
  3108. min_semi_end = pre_end;
  3109. }
  3110. #endif
  3111. if (min_semi_end > str && start <= min_semi_end) {
  3112. goto end_buf;
  3113. }
  3114. }
  3115. else {
  3116. min_semi_end = (UChar* )end;
  3117. goto end_buf;
  3118. }
  3119. }
  3120. else if ((reg->anchor & ANCHOR_ANYCHAR_STAR_ML)) {
  3121. goto begin_position;
  3122. }
  3123. }
  3124. else if (str == end) { /* empty string */
  3125. static const UChar* address_for_empty_string = (UChar* )"";
  3126. #ifdef ONIG_DEBUG_SEARCH
  3127. fprintf(stderr, "onig_search: empty string.\n");
  3128. #endif
  3129. if (reg->threshold_len == 0) {
  3130. start = end = str = address_for_empty_string;
  3131. s = (UChar* )start;
  3132. prev = (UChar* )NULL;
  3133. MATCH_ARG_INIT(msa, option, region, start);
  3134. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  3135. msa.state_check_buff = (void* )0;
  3136. msa.state_check_buff_size = 0; /* NO NEED, for valgrind */
  3137. #endif
  3138. MATCH_AND_RETURN_CHECK(end);
  3139. goto mismatch;
  3140. }
  3141. goto mismatch_no_msa;
  3142. }
  3143. #ifdef ONIG_DEBUG_SEARCH
  3144. fprintf(stderr, "onig_search(apply anchor): end: %d, start: %d, range: %d\n",
  3145. (int )(end - str), (int )(start - str), (int )(range - str));
  3146. #endif
  3147. MATCH_ARG_INIT(msa, option, region, orig_start);
  3148. #ifdef USE_COMBINATION_EXPLOSION_CHECK
  3149. {
  3150. int offset = (MIN(start, range) - str);
  3151. STATE_CHECK_BUFF_INIT(msa, end - str, offset, reg->num_comb_exp_check);
  3152. }
  3153. #endif
  3154. s = (UChar* )start;
  3155. if (range > start) { /* forward search */
  3156. if (s > str)
  3157. prev = onigenc_get_prev_char_head(reg->enc, str, s);
  3158. else
  3159. prev = (UChar* )NULL;
  3160. if (reg->optimize != ONIG_OPTIMIZE_NONE) {
  3161. UChar *sch_range, *low, *high, *low_prev;
  3162. sch_range = (UChar* )range;
  3163. if (reg->dmax != 0) {
  3164. if (reg->dmax == ONIG_INFINITE_DISTANCE)
  3165. sch_range = (UChar* )end;
  3166. else {
  3167. sch_range += reg->dmax;
  3168. if (sch_range > end) sch_range = (UChar* )end;
  3169. }
  3170. }
  3171. if ((end - start) < reg->threshold_len)
  3172. goto mismatch;
  3173. if (reg->dmax != ONIG_INFINITE_DISTANCE) {
  3174. do {
  3175. if (! forward_search_range(reg, str, end, s, sch_range,
  3176. &low, &high, &low_prev)) goto mismatch;
  3177. if (s < low) {
  3178. s = low;
  3179. prev = low_prev;
  3180. }
  3181. while (s <= high) {
  3182. MATCH_AND_RETURN_CHECK(orig_range);
  3183. prev = s;
  3184. s += enclen(reg->enc, s);
  3185. }
  3186. } while (s < range);
  3187. goto mismatch;
  3188. }
  3189. else { /* check only. */
  3190. if (! forward_search_range(reg, str, end, s, sch_range,
  3191. &low, &high, (UChar** )NULL)) goto mismatch;
  3192. if ((reg->anchor & ANCHOR_ANYCHAR_STAR) != 0) {
  3193. do {
  3194. MATCH_AND_RETURN_CHECK(orig_range);
  3195. prev = s;
  3196. s += enclen(reg->enc, s);
  3197. while (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end) && s < range) {
  3198. prev = s;
  3199. s += enclen(reg->enc, s);
  3200. }
  3201. } while (s < range);
  3202. goto mismatch;
  3203. }
  3204. }
  3205. }
  3206. do {
  3207. MATCH_AND_RETURN_CHECK(orig_range);
  3208. prev = s;
  3209. s += enclen(reg->enc, s);
  3210. } while (s < range);
  3211. if (s == range) { /* because empty match with /$/. */
  3212. MATCH_AND_RETURN_CHECK(orig_range);
  3213. }
  3214. }
  3215. else { /* backward search */
  3216. #ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
  3217. if (orig_start < end)
  3218. orig_start += enclen(reg->enc, orig_start); /* is upper range */
  3219. #endif
  3220. if (reg->optimize != ONIG_OPTIMIZE_NONE) {
  3221. UChar *low, *high, *adjrange, *sch_start;
  3222. if (range < end)
  3223. adjrange = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc, str, range);
  3224. else
  3225. adjrange = (UChar* )end;
  3226. if (reg->dmax != ONIG_INFINITE_DISTANCE &&
  3227. (end - range) >= reg->threshold_len) {
  3228. do {
  3229. sch_start = s + reg->dmax;
  3230. if (sch_start > end) sch_start = (UChar* )end;
  3231. if (backward_search_range(reg, str, end, sch_start, range, adjrange,
  3232. &low, &high) <= 0)
  3233. goto mismatch;
  3234. if (s > high)
  3235. s = high;
  3236. while (s >= low) {
  3237. prev = onigenc_get_prev_char_head(reg->enc, str, s);
  3238. MATCH_AND_RETURN_CHECK(orig_start);
  3239. s = prev;
  3240. }
  3241. } while (s >= range);
  3242. goto mismatch;
  3243. }
  3244. else { /* check only. */
  3245. if ((end - range) < reg->threshold_len) goto mismatch;
  3246. sch_start = s;
  3247. if (reg->dmax != 0) {
  3248. if (reg->dmax == ONIG_INFINITE_DISTANCE)
  3249. sch_start = (UChar* )end;
  3250. else {
  3251. sch_start += reg->dmax;
  3252. if (sch_start > end) sch_start = (UChar* )end;
  3253. else
  3254. sch_start = ONIGENC_LEFT_ADJUST_CHAR_HEAD(reg->enc,
  3255. start, sch_start);
  3256. }
  3257. }
  3258. if (backward_search_range(reg, str, end, sch_start, range, adjrange,
  3259. &low, &high) <= 0) goto mismatch;
  3260. }
  3261. }
  3262. do {
  3263. prev = onigenc_get_prev_char_head(reg->enc, str, s);
  3264. MATCH_AND_RETURN_CHECK(orig_start);
  3265. s = prev;
  3266. } while (s >= range);
  3267. }
  3268. mismatch:
  3269. #ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
  3270. if (IS_FIND_LONGEST(reg->options)) {
  3271. if (msa.best_len >= 0) {
  3272. s = msa.best_s;
  3273. goto match;
  3274. }
  3275. }
  3276. #endif
  3277. r = ONIG_MISMATCH;
  3278. finish:
  3279. MATCH_ARG_FREE(msa);
  3280. ONIG_STATE_DEC_THREAD(reg);
  3281. /* If result is mismatch and no FIND_NOT_EMPTY option,
  3282. then the region is not setted in match_at(). */
  3283. if (IS_FIND_NOT_EMPTY(reg->options) && region
  3284. #ifdef USE_POSIX_API_REGION_OPTION
  3285. && !IS_POSIX_REGION(option)
  3286. #endif
  3287. ) {
  3288. onig_region_clear(region);
  3289. }
  3290. #ifdef ONIG_DEBUG
  3291. if (r != ONIG_MISMATCH)
  3292. fprintf(stderr, "onig_search: error %d\n", r);
  3293. #endif
  3294. return r;
  3295. mismatch_no_msa:
  3296. r = ONIG_MISMATCH;
  3297. finish_no_msa:
  3298. ONIG_STATE_DEC_THREAD(reg);
  3299. #ifdef ONIG_DEBUG
  3300. if (r != ONIG_MISMATCH)
  3301. fprintf(stderr, "onig_search: error %d\n", r);
  3302. #endif
  3303. return r;
  3304. match:
  3305. ONIG_STATE_DEC_THREAD(reg);
  3306. MATCH_ARG_FREE(msa);
  3307. return s - str;
  3308. }
  3309. extern OnigEncoding
  3310. onig_get_encoding(regex_t* reg)
  3311. {
  3312. return reg->enc;
  3313. }
  3314. extern OnigOptionType
  3315. onig_get_options(regex_t* reg)
  3316. {
  3317. return reg->options;
  3318. }
  3319. extern OnigCaseFoldType
  3320. onig_get_case_fold_flag(regex_t* reg)
  3321. {
  3322. return reg->case_fold_flag;
  3323. }
  3324. extern OnigSyntaxType*
  3325. onig_get_syntax(regex_t* reg)
  3326. {
  3327. return reg->syntax;
  3328. }
  3329. extern int
  3330. onig_number_of_captures(regex_t* reg)
  3331. {
  3332. return reg->num_mem;
  3333. }
  3334. extern int
  3335. onig_number_of_capture_histories(regex_t* reg)
  3336. {
  3337. #ifdef USE_CAPTURE_HISTORY
  3338. int i, n;
  3339. n = 0;
  3340. for (i = 0; i <= ONIG_MAX_CAPTURE_HISTORY_GROUP; i++) {
  3341. if (BIT_STATUS_AT(reg->capture_history, i) != 0)
  3342. n++;
  3343. }
  3344. return n;
  3345. #else
  3346. return 0;
  3347. #endif
  3348. }
  3349. extern void
  3350. onig_copy_encoding(OnigEncoding to, OnigEncoding from)
  3351. {
  3352. *to = *from;
  3353. }