Skip to content

Commit d236e5b

Browse files
committed
fix "rewrite_by_lua_block"
1 parent 50eb404 commit d236e5b

File tree

2 files changed

+57
-70
lines changed

2 files changed

+57
-70
lines changed

lex.go

Lines changed: 56 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -160,23 +160,6 @@ func tokenize(reader io.Reader, tokenCh chan NgxToken, options LexOptions) {
160160
tokenStr := token.String()
161161
if ext, ok := externalLexers[tokenStr]; ok {
162162
emit(tokenStartLine, false, nil)
163-
// for {
164-
// tok, err := ext.Lex()
165-
166-
// if errors.Is(err, StopExtLexer{}) {
167-
// break
168-
// }
169-
170-
// if err != nil {
171-
// emit(tokenStartLine, false, &ParseError{
172-
// File: &lexerFile,
173-
// What: err.Error(),
174-
// Line: &tokenLine, // TODO: I See this used but never updated
175-
// })
176-
// continue
177-
// }
178-
// tokenCh <- tok
179-
// }
180163
externalScanner.tokenLine = tokenLine
181164
extTokenCh := ext.Lex(tokenStr)
182165
for tok := range extTokenCh {
@@ -345,21 +328,18 @@ func (ll *LuaLexer) Lex(matchedToken string) <-chan NgxToken {
345328
tokenCh := make(chan NgxToken)
346329

347330
tokenDepth := 0
348-
// var leadingWhitespace strings.Builder
349331

350332
go func() {
351333
defer close(tokenCh)
352334
var tok strings.Builder
353335
var inQuotes bool
354-
355336

356337
if matchedToken == "set_by_lua_block" {
357338
arg := ""
358339
for {
359340
if !ll.s.Scan() {
360341
return
361342
}
362-
363343
next := ll.s.Text()
364344
if isSpace(next) {
365345
if arg != "" {
@@ -376,36 +356,29 @@ func (ll *LuaLexer) Lex(matchedToken string) <-chan NgxToken {
376356
}
377357
arg += next
378358
}
379-
}
359+
// skip leading whitespace after the return value
360+
for {
361+
if !ll.s.Scan() {
362+
return
363+
}
364+
next := ll.s.Text()
380365

381-
for {
382-
if !ll.s.Scan() {
383-
return
384-
}
385-
if next := ll.s.Text(); !isSpace(next) {
386-
break
366+
if !isSpace(next) {
367+
if next != "{" {
368+
lineno := ll.s.Line()
369+
tokenCh <- NgxToken{Error: &ParseError{File: &lexerFile, What: `unexpected "}"`, Line: &lineno}}
370+
return
371+
}
372+
tokenDepth++
373+
break
374+
}
387375
}
388376
}
389377

390-
if !ll.s.Scan() {
391-
// TODO: err?
392-
return
393-
}
394-
395-
if next := ll.s.Text(); next != "{" {
396-
lineno := ll.s.Line()
397-
tokenCh <- NgxToken{Error: &ParseError{File: &lexerFile, What: `unexpected "}"`, Line: &lineno}}
398-
return
399-
400-
}
401-
402-
tokenDepth ++
403-
404-
// TODO: check for opening brace?
405-
378+
// Grab everything in Lua block as a single token and watch for curly brace '{' in strings
406379
for {
407380
if !ll.s.Scan() {
408-
return // shrug emoji
381+
return
409382
}
410383

411384
next := ll.s.Text()
@@ -415,13 +388,12 @@ func (ll *LuaLexer) Lex(matchedToken string) <-chan NgxToken {
415388

416389
}
417390

418-
419-
420-
421-
422391
switch {
423392
case next == "{" && !inQuotes:
424393
tokenDepth++
394+
if tokenDepth > 1 { // not the first open brace
395+
tok.WriteString(next)
396+
}
425397

426398
case next == "}" && !inQuotes:
427399
tokenDepth--
@@ -431,47 +403,62 @@ func (ll *LuaLexer) Lex(matchedToken string) <-chan NgxToken {
431403
return
432404
}
433405

406+
if tokenDepth > 0 { // not the last close brace for it to be 0
407+
tok.WriteString(next)
408+
}
409+
434410
if tokenDepth == 0 {
435-
// tokenCh <- NgxToken{Value: next, Line: 0}
436-
// Before finishing the block, prepend any leading whitespace.
437-
// finalTokenValue := leadingWhitespace.String() + tok.String()
438411
tokenCh <- NgxToken{Value: tok.String(), Line: ll.s.Line(), IsQuoted: true}
439-
// tokenCh <- NgxToken{Value: finalTokenValue, Line: ll.s.Line(), IsQuoted: true}
440-
// tok.Reset()
441-
// leadingWhitespace.Reset()
442412
tokenCh <- NgxToken{Value: ";", Line: ll.s.Line(), IsQuoted: false} // For an end to the Lua string, seems hacky.
443413
// See: https://github.com/nginxinc/crossplane/blob/master/crossplane/ext/lua.py#L122C25-L122C41
444414
return
445415
}
416+
446417
case next == `"` || next == "'":
447-
if !inQuotes {
448-
inQuotes = true
449-
} else {
450-
inQuotes = false
451-
}
418+
inQuotes = !inQuotes
452419
tok.WriteString(next)
453420

454-
// case isSpace(next):
455-
// if tok.Len() == 0 {
456-
// continue
457-
// }
458-
// tok.WriteString(next)
459421
default:
460422
// Expected first token encountered to be a "{" to open a Lua block. Handle any other non-whitespace
461423
// character to mean we are not about to tokenize Lua.
424+
425+
// ignoring everything until first open brace where tokenDepth > 0
426+
if isSpace(next) && tokenDepth == 0 {
427+
continue
428+
}
429+
430+
// stricly check that first non space character is {
462431
if tokenDepth == 0 {
463432
tokenCh <- NgxToken{Value: next, Line: ll.s.Line(), IsQuoted: false}
464433
return
465434
}
466435
tok.WriteString(next)
467436
}
468-
469-
// if tokenDepth == 0 {
470-
// return
471-
// }
472-
473437
}
474438
}()
475439

476440
return tokenCh
477441
}
442+
443+
// TODO: 1. check for opening brace?
444+
// assume nested parathesis only with () and [], no curly parathesis
445+
// ignore space until first {
446+
// // rewrite_by_lua_block x will be accepted -- work on this case
447+
// stricly check that first non space character is {
448+
449+
/* commit 2. do we strictly check for equal number of open and close braces rewite_by_lua_block { {1,2 // parser will use close from outside of lua block
450+
451+
http{ server {
452+
rewite_by_lua_block { {1,2
453+
454+
}}
455+
456+
==>
457+
scenario 1
458+
error for http and server block
459+
rewite_by_lua_block { {1,2}}
460+
461+
scenario 2
462+
error for rewite_by_lua_block with insufficient close
463+
http and server parse succeeds
464+
*/

lex_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ func TestLex(t *testing.T) {
411411
fixture := fixture
412412
t.Run(fixture.name, func(t *testing.T) {
413413
t.Parallel()
414-
// if fixture.name != "lua-block-simple" {
414+
// if fixture.name != "lua-block-tricky" {
415415
// t.Skip()
416416
// }
417417
path := getTestConfigPath(fixture.name, "nginx.conf")

0 commit comments

Comments
 (0)