PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/bundle/ngx_lua-0.9.2/t/037-gsub.t

https://github.com/dome/lixen_app
Unknown | 575 lines | 466 code | 109 blank | 0 comment | 0 complexity | bd800dd08f4c8217a6695291bff0e4ba MD5 | raw file
Possible License(s): BSD-2-Clause, BSD-3-Clause
  1. # vim:set ft= ts=4 sw=4 et fdm=marker:
  2. use lib 'lib';
  3. use t::TestNginxLua;
  4. #worker_connections(1014);
  5. #master_on();
  6. #workers(2);
  7. log_level('warn');
  8. repeat_each(2);
  9. plan tests => repeat_each() * (blocks() * 2 + 14);
  10. #no_diff();
  11. no_long_string();
  12. run_tests();
  13. __DATA__
  14. === TEST 1: sanity
  15. --- config
  16. location /re {
  17. content_by_lua '
  18. local s, n = ngx.re.gsub("[hello, world]", "[a-z]+", "howdy")
  19. ngx.say(s)
  20. ngx.say(n)
  21. ';
  22. }
  23. --- request
  24. GET /re
  25. --- response_body
  26. [howdy, howdy]
  27. 2
  28. === TEST 2: trimmed
  29. --- config
  30. location /re {
  31. content_by_lua '
  32. local s, n = ngx.re.gsub("hello, world", "[a-z]+", "howdy")
  33. ngx.say(s)
  34. ngx.say(n)
  35. ';
  36. }
  37. --- request
  38. GET /re
  39. --- response_body
  40. howdy, howdy
  41. 2
  42. === TEST 3: not matched
  43. --- config
  44. location /re {
  45. content_by_lua '
  46. local s, n = ngx.re.gsub("hello, world", "[A-Z]+", "howdy")
  47. ngx.say(s)
  48. ngx.say(n)
  49. ';
  50. }
  51. --- request
  52. GET /re
  53. --- response_body
  54. hello, world
  55. 0
  56. === TEST 4: replace by function (trimmed)
  57. --- config
  58. location /re {
  59. content_by_lua '
  60. local f = function (m)
  61. return "[" .. m[0] .. "," .. m[1] .. "]"
  62. end
  63. local s, n = ngx.re.gsub("hello, world", "([a-z])[a-z]+", f)
  64. ngx.say(s)
  65. ngx.say(n)
  66. ';
  67. }
  68. --- request
  69. GET /re
  70. --- response_body
  71. [hello,h], [world,w]
  72. 2
  73. === TEST 5: replace by function (not trimmed)
  74. --- config
  75. location /re {
  76. content_by_lua '
  77. local f = function (m)
  78. return "[" .. m[0] .. "," .. m[1] .. "]"
  79. end
  80. local s, n = ngx.re.gsub("{hello, world}", "([a-z])[a-z]+", f)
  81. ngx.say(s)
  82. ngx.say(n)
  83. ';
  84. }
  85. --- request
  86. GET /re
  87. --- response_body
  88. {[hello,h], [world,w]}
  89. 2
  90. === TEST 6: replace by script (trimmed)
  91. --- config
  92. location /re {
  93. content_by_lua '
  94. local s, n = ngx.re.gsub("hello, world", "([a-z])[a-z]+", "[$0,$1]")
  95. ngx.say(s)
  96. ngx.say(n)
  97. ';
  98. }
  99. --- request
  100. GET /re
  101. --- response_body
  102. [hello,h], [world,w]
  103. 2
  104. === TEST 7: replace by script (not trimmed)
  105. --- config
  106. location /re {
  107. content_by_lua '
  108. local s, n = ngx.re.gsub("{hello, world}", "([a-z])[a-z]+", "[$0,$1]")
  109. ngx.say(s)
  110. ngx.say(n)
  111. ';
  112. }
  113. --- request
  114. GET /re
  115. --- response_body
  116. {[hello,h], [world,w]}
  117. 2
  118. === TEST 8: set_by_lua
  119. --- config
  120. location /re {
  121. set_by_lua $res '
  122. local f = function (m)
  123. return "[" .. m[0] .. "," .. m[1] .. "]"
  124. end
  125. local s, n = ngx.re.gsub("{hello, world}", "([a-z])[a-z]+", f)
  126. return s
  127. ';
  128. echo $res;
  129. }
  130. --- request
  131. GET /re
  132. --- response_body
  133. {[hello,h], [world,w]}
  134. === TEST 9: look-behind assertion
  135. --- config
  136. location /re {
  137. content_by_lua '
  138. local s, n = ngx.re.gsub("{foobarbaz}", "(?<=foo)bar|(?<=bar)baz", "h$0")
  139. ngx.say(s)
  140. ngx.say(n)
  141. ';
  142. }
  143. --- request
  144. GET /re
  145. --- response_body
  146. {foohbarhbaz}
  147. 2
  148. === TEST 10: gsub with a patch matching an empty substring (string template)
  149. --- config
  150. location /re {
  151. content_by_lua '
  152. local s, n = ngx.re.gsub("hello", "a|", "b")
  153. ngx.say("s: ", s)
  154. ngx.say("n: ", n)
  155. ';
  156. }
  157. --- request
  158. GET /re
  159. --- response_body
  160. s: bhbeblblbob
  161. n: 6
  162. --- no_error_log
  163. [error]
  164. === TEST 11: gsub with a patch matching an empty substring (string template, empty subj)
  165. --- config
  166. location /re {
  167. content_by_lua '
  168. local s, n = ngx.re.gsub("", "a|", "b")
  169. ngx.say("s: ", s)
  170. ngx.say("n: ", n)
  171. ';
  172. }
  173. --- request
  174. GET /re
  175. --- response_body
  176. s: b
  177. n: 1
  178. --- no_error_log
  179. [error]
  180. === TEST 12: gsub with a patch matching an empty substring (func)
  181. --- config
  182. location /re {
  183. content_by_lua '
  184. local s, n = ngx.re.gsub("hello", "a|", function () return "b" end)
  185. ngx.say("s: ", s)
  186. ngx.say("n: ", n)
  187. ';
  188. }
  189. --- request
  190. GET /re
  191. --- response_body
  192. s: bhbeblblbob
  193. n: 6
  194. --- no_error_log
  195. [error]
  196. === TEST 13: gsub with a patch matching an empty substring (func, empty subj)
  197. --- config
  198. location /re {
  199. content_by_lua '
  200. local s, n = ngx.re.gsub("", "a|", function () return "b" end)
  201. ngx.say("s: ", s)
  202. ngx.say("n: ", n)
  203. ';
  204. }
  205. --- request
  206. GET /re
  207. --- response_body
  208. s: b
  209. n: 1
  210. --- no_error_log
  211. [error]
  212. === TEST 14: big subject string exceeding the luabuf chunk size (with trailing unmatched data, func repl)
  213. --- config
  214. location /re {
  215. content_by_lua '
  216. local subj = string.rep("a", 8000)
  217. .. string.rep("b", 1000)
  218. .. string.rep("a", 8000)
  219. .. string.rep("b", 1000)
  220. .. "aaa"
  221. local function repl(m)
  222. return string.rep("c", string.len(m[0]))
  223. end
  224. local s, n = ngx.re.gsub(subj, "b+", repl)
  225. ngx.say(s)
  226. ngx.say(n)
  227. ';
  228. }
  229. --- request
  230. GET /re
  231. --- response_body eval
  232. ("a" x 8000) . ("c" x 1000) . ("a" x 8000) . ("c" x 1000)
  233. . "aaa
  234. 2
  235. "
  236. --- no_error_log
  237. [error]
  238. === TEST 15: big subject string exceeding the luabuf chunk size (without trailing unmatched data, func repl)
  239. --- config
  240. location /re {
  241. content_by_lua '
  242. local subj = string.rep("a", 8000)
  243. .. string.rep("b", 1000)
  244. .. string.rep("a", 8000)
  245. .. string.rep("b", 1000)
  246. local function repl(m)
  247. return string.rep("c", string.len(m[0]))
  248. end
  249. local s, n = ngx.re.gsub(subj, "b+", repl)
  250. ngx.say(s)
  251. ngx.say(n)
  252. ';
  253. }
  254. --- request
  255. GET /re
  256. --- response_body eval
  257. ("a" x 8000) . ("c" x 1000) . ("a" x 8000) . ("c" x 1000)
  258. . "\n2\n"
  259. --- no_error_log
  260. [error]
  261. === TEST 16: big subject string exceeding the luabuf chunk size (with trailing unmatched data, str repl)
  262. --- config
  263. location /re {
  264. content_by_lua '
  265. local subj = string.rep("a", 8000)
  266. .. string.rep("b", 1000)
  267. .. string.rep("a", 8000)
  268. .. string.rep("b", 1000)
  269. .. "aaa"
  270. local s, n = ngx.re.gsub(subj, "b(b+)(b)", "$1 $2")
  271. ngx.say(s)
  272. ngx.say(n)
  273. ';
  274. }
  275. --- request
  276. GET /re
  277. --- response_body eval
  278. ("a" x 8000) . ("b" x 998) . " b" . ("a" x 8000) . ("b" x 998) . " baaa
  279. 2
  280. "
  281. --- no_error_log
  282. [error]
  283. === TEST 17: big subject string exceeding the luabuf chunk size (without trailing unmatched data, str repl)
  284. --- config
  285. location /re {
  286. content_by_lua '
  287. local subj = string.rep("a", 8000)
  288. .. string.rep("b", 1000)
  289. .. string.rep("a", 8000)
  290. .. string.rep("b", 1000)
  291. local s, n = ngx.re.gsub(subj, "b(b+)(b)", "$1 $2")
  292. ngx.say(s)
  293. ngx.say(n)
  294. ';
  295. }
  296. --- request
  297. GET /re
  298. --- response_body eval
  299. ("a" x 8000) . ("b" x 998) . " b" . ("a" x 8000) . ("b" x 998) . " b\n2\n"
  300. --- no_error_log
  301. [error]
  302. === TEST 18: named pattern repl w/ callback
  303. --- config
  304. location /re {
  305. content_by_lua '
  306. local repl = function (m)
  307. return "[" .. m[0] .. "," .. m["first"] .. "]"
  308. end
  309. local s, n = ngx.re.gsub("hello, world", "(?<first>[a-z])[a-z]+", repl)
  310. ngx.say(s)
  311. ngx.say(n)
  312. ';
  313. }
  314. --- request
  315. GET /re
  316. --- response_body
  317. [hello,h], [world,w]
  318. 2
  319. === TEST 19: $0 without parens
  320. --- config
  321. location /re {
  322. content_by_lua '
  323. local s, n = ngx.re.gsub("a b c d", [[\w]], "[$0]")
  324. ngx.say(s)
  325. ngx.say(n)
  326. ';
  327. }
  328. --- request
  329. GET /re
  330. --- response_body
  331. [a] [b] [c] [d]
  332. 4
  333. --- no_error_log
  334. [error]
  335. === TEST 20: bad UTF-8
  336. --- config
  337. location = /t {
  338. content_by_lua '
  339. local target = "你好"
  340. local regex = "你好"
  341. -- Note the D here
  342. local s, n, err = ngx.re.gsub(string.sub(target, 1, 4), regex, "", "u")
  343. if s then
  344. ngx.say(s, ": ", n)
  345. else
  346. ngx.say("error: ", err)
  347. end
  348. ';
  349. }
  350. --- request
  351. GET /t
  352. --- response_body_like chop
  353. error: pcre_exec\(\) failed: -10
  354. --- no_error_log
  355. [error]
  356. === TEST 21: UTF-8 mode without UTF-8 sequence checks
  357. --- config
  358. location /re {
  359. content_by_lua '
  360. local s, n, err = ngx.re.gsub("你好", ".", "a", "U")
  361. if s then
  362. ngx.say("s: ", s)
  363. end
  364. ';
  365. }
  366. --- stap
  367. probe process("$LIBPCRE_PATH").function("pcre_compile") {
  368. printf("compile opts: %x\n", $options)
  369. }
  370. probe process("$LIBPCRE_PATH").function("pcre_exec") {
  371. printf("exec opts: %x\n", $options)
  372. }
  373. --- stap_out
  374. compile opts: 800
  375. exec opts: 2000
  376. exec opts: 2000
  377. exec opts: 2000
  378. --- request
  379. GET /re
  380. --- response_body
  381. s: aa
  382. --- no_error_log
  383. [error]
  384. === TEST 22: UTF-8 mode with UTF-8 sequence checks
  385. --- config
  386. location /re {
  387. content_by_lua '
  388. local s, n, err = ngx.re.gsub("你好", ".", "a", "u")
  389. if s then
  390. ngx.say("s: ", s)
  391. end
  392. ';
  393. }
  394. --- stap
  395. probe process("$LIBPCRE_PATH").function("pcre_compile") {
  396. printf("compile opts: %x\n", $options)
  397. }
  398. probe process("$LIBPCRE_PATH").function("pcre_exec") {
  399. printf("exec opts: %x\n", $options)
  400. }
  401. --- stap_out
  402. compile opts: 800
  403. exec opts: 0
  404. exec opts: 0
  405. exec opts: 0
  406. --- request
  407. GET /re
  408. --- response_body
  409. s: aa
  410. --- no_error_log
  411. [error]
  412. === TEST 23: just hit match limit
  413. --- http_config
  414. lua_regex_match_limit 5600;
  415. --- config
  416. location /re {
  417. content_by_lua_file html/a.lua;
  418. }
  419. --- user_files
  420. >>> a.lua
  421. local re = [==[(?i:([\s'\"`´’‘\(\)]*)?([\d\w]+)([\s'\"`´’‘\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´’‘\(\)]*)?\2|([\s'\"`´’‘\(\)]*)?([\d\w]+)([\s'\"`´’‘\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´’‘\(\)]*)?(?!\6)([\d\w]+))]==]
  422. s = string.rep([[ABCDEFG]], 10)
  423. local start = ngx.now()
  424. local res, cnt, err = ngx.re.gsub(s, re, "", "o")
  425. --[[
  426. ngx.update_time()
  427. local elapsed = ngx.now() - start
  428. ngx.say(elapsed, " sec elapsed.")
  429. ]]
  430. if err then
  431. ngx.say("error: ", err)
  432. return
  433. end
  434. ngx.say("gsub: ", cnt)
  435. --- request
  436. GET /re
  437. --- response_body
  438. error: pcre_exec() failed: -8
  439. === TEST 24: just not hit match limit
  440. --- http_config
  441. lua_regex_match_limit 5700;
  442. --- config
  443. location /re {
  444. content_by_lua_file html/a.lua;
  445. }
  446. --- user_files
  447. >>> a.lua
  448. local re = [==[(?i:([\s'\"`´’‘\(\)]*)?([\d\w]+)([\s'\"`´’‘\(\)]*)?(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´’‘\(\)]*)?\2|([\s'\"`´’‘\(\)]*)?([\d\w]+)([\s'\"`´’‘\(\)]*)?(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´’‘\(\)]*)?(?!\6)([\d\w]+))]==]
  449. local s = string.rep([[ABCDEFG]], 10)
  450. local start = ngx.now()
  451. local res, cnt, err = ngx.re.gsub(s, re, "", "o")
  452. --[[
  453. ngx.update_time()
  454. local elapsed = ngx.now() - start
  455. ngx.say(elapsed, " sec elapsed.")
  456. ]]
  457. if err then
  458. ngx.say("error: ", err)
  459. return
  460. end
  461. ngx.say("gsub: ", cnt)
  462. --- request
  463. GET /re
  464. --- response_body
  465. gsub: 0
  466. --- timeout: 10