Skip to content

Commit 8d10de4

Browse files
committed
Merge branch 'nlb-1424-map' into 'master'
fix: add map directive parameters to parse payload without parsing See merge request f5/nginx/crossplane-go!28
2 parents 7079cb5 + 297a777 commit 8d10de4

File tree

5 files changed

+229
-1
lines changed

5 files changed

+229
-1
lines changed

build_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ var compareFixtures = []compareFixture{
356356
{"empty-value-map", ParseOptions{}},
357357
{"russian-text", ParseOptions{}},
358358
{"quoted-right-brace", ParseOptions{}},
359-
{"directive-with-space", ParseOptions{}},
359+
{"directive-with-space", ParseOptions{ErrorOnUnknownDirectives: true}},
360360
{"empty-config", ParseOptions{}},
361361
}
362362

parse.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,23 @@ func (p *parser) parse(parsing *Config, tokens <-chan NgxToken, ctx blockCtx, co
260260
}
261261
}
262262

263+
// if inside map block - add contents to payload, but do not parse further
264+
if len(ctx) > 0 && (ctx[len(ctx)-1] == "map" || ctx[len(ctx)-1] == "charset_map") {
265+
mapErr := analyzeMapContents(parsing.File, stmt, t.Value)
266+
if mapErr != nil && p.options.StopParsingOnError {
267+
return nil, mapErr
268+
} else if mapErr != nil {
269+
p.handleError(parsing, mapErr)
270+
// consume invalid block
271+
if t.Value == "{" && !t.IsQuoted {
272+
_, _ = p.parse(parsing, tokens, nil, true)
273+
}
274+
continue
275+
}
276+
parsed = append(parsed, stmt)
277+
continue
278+
}
279+
263280
// consume the directive if it is ignored and move on
264281
if contains(p.options.IgnoreDirectives, stmt.Directive) {
265282
// if this directive was a block consume it too
@@ -417,3 +434,21 @@ func (p *parser) isAcyclic() bool {
417434
}
418435
return fileCount != len(p.includeInDegree)
419436
}
437+
438+
func analyzeMapContents(fname string, stmt *Directive, term string) error {
439+
if term != ";" {
440+
return &ParseError{
441+
What: fmt.Sprintf(`unexpected "%s"`, term),
442+
File: &fname,
443+
Line: &stmt.Line,
444+
}
445+
}
446+
if len(stmt.Args) != 1 {
447+
return &ParseError{
448+
What: "invalid number of the map parameters",
449+
File: &fname,
450+
Line: &stmt.Line,
451+
}
452+
}
453+
return nil
454+
}

parse_test.go

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,178 @@ var parseFixtures = []parseFixture{
907907
},
908908
},
909909
}},
910+
{"directive-with-space", "", ParseOptions{ErrorOnUnknownDirectives: true}, Payload{
911+
Status: "ok",
912+
Config: []Config{
913+
{
914+
File: getTestConfigPath("directive-with-space", "nginx.conf"),
915+
Status: "ok",
916+
Parsed: Directives{
917+
{
918+
Directive: "events",
919+
Args: []string{},
920+
Line: 1,
921+
Block: Directives{},
922+
},
923+
{
924+
Directive: "http",
925+
Args: []string{},
926+
Line: 3,
927+
Block: Directives{
928+
{
929+
Directive: "map",
930+
Args: []string{"$http_user_agent", "$mobile"},
931+
Line: 4,
932+
Block: Directives{
933+
{
934+
Directive: "default",
935+
Args: []string{"0"},
936+
Line: 5,
937+
Block: Directives{},
938+
},
939+
{
940+
Directive: "~Opera Mini",
941+
Args: []string{"1"},
942+
Line: 6,
943+
Block: Directives{},
944+
},
945+
},
946+
},
947+
{
948+
Directive: "charset_map",
949+
Args: []string{"koi8-r", "utf-8"},
950+
Line: 9,
951+
Block: Directives{
952+
{
953+
Directive: "C0",
954+
Args: []string{"D18E"},
955+
Line: 10,
956+
Block: Directives{},
957+
},
958+
{
959+
Directive: "C1",
960+
Args: []string{"D0B0"},
961+
Line: 11,
962+
Block: Directives{},
963+
},
964+
},
965+
},
966+
},
967+
},
968+
},
969+
},
970+
},
971+
}},
972+
{"invalid-map", "", ParseOptions{ErrorOnUnknownDirectives: true}, Payload{
973+
Status: "failed",
974+
Errors: []PayloadError{
975+
{
976+
File: getTestConfigPath("invalid-map", "nginx.conf"),
977+
Error: &ParseError{
978+
`unexpected "{"`,
979+
pStr(getTestConfigPath("invalid-map", "nginx.conf")),
980+
pInt(7),
981+
nil,
982+
},
983+
Line: pInt(7),
984+
},
985+
{
986+
File: getTestConfigPath("invalid-map", "nginx.conf"),
987+
Error: &ParseError{
988+
`invalid number of the map parameters`,
989+
pStr(getTestConfigPath("invalid-map", "nginx.conf")),
990+
pInt(10),
991+
nil,
992+
},
993+
Line: pInt(10),
994+
},
995+
{
996+
File: getTestConfigPath("invalid-map", "nginx.conf"),
997+
Error: &ParseError{
998+
`invalid number of the map parameters`,
999+
pStr(getTestConfigPath("invalid-map", "nginx.conf")),
1000+
pInt(14),
1001+
nil,
1002+
},
1003+
Line: pInt(14),
1004+
},
1005+
},
1006+
Config: []Config{
1007+
{
1008+
File: getTestConfigPath("invalid-map", "nginx.conf"),
1009+
Status: "failed",
1010+
Errors: []ConfigError{
1011+
{
1012+
Error: &ParseError{
1013+
`unexpected "{"`,
1014+
pStr(getTestConfigPath("invalid-map", "nginx.conf")),
1015+
pInt(7),
1016+
nil,
1017+
},
1018+
Line: pInt(7),
1019+
},
1020+
{
1021+
Error: &ParseError{
1022+
`invalid number of the map parameters`,
1023+
pStr(getTestConfigPath("invalid-map", "nginx.conf")),
1024+
pInt(10),
1025+
nil,
1026+
},
1027+
Line: pInt(10),
1028+
},
1029+
{
1030+
Error: &ParseError{
1031+
`invalid number of the map parameters`,
1032+
pStr(getTestConfigPath("invalid-map", "nginx.conf")),
1033+
pInt(14),
1034+
nil,
1035+
},
1036+
Line: pInt(14),
1037+
},
1038+
},
1039+
Parsed: Directives{
1040+
{
1041+
Directive: "events",
1042+
Args: []string{},
1043+
Line: 1,
1044+
Block: Directives{},
1045+
},
1046+
{
1047+
Directive: "http",
1048+
Args: []string{},
1049+
Line: 3,
1050+
Block: Directives{
1051+
{
1052+
Directive: "map",
1053+
Args: []string{"$http_user_agent", "$mobile"},
1054+
Line: 4,
1055+
Block: Directives{
1056+
{
1057+
Directive: "default",
1058+
Args: []string{"0"},
1059+
Line: 5,
1060+
Block: Directives{},
1061+
},
1062+
{
1063+
Directive: "~Opera Mini",
1064+
Args: []string{"1"},
1065+
Line: 6,
1066+
Block: Directives{},
1067+
},
1068+
},
1069+
},
1070+
{
1071+
Directive: "charset_map",
1072+
Args: []string{"koi8-r", "utf-8"},
1073+
Line: 13,
1074+
Block: Directives{},
1075+
},
1076+
},
1077+
},
1078+
},
1079+
},
1080+
},
1081+
}},
9101082
}
9111083

9121084
func TestParse(t *testing.T) {

testdata/configs/directive-with-space/nginx.conf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,9 @@ http {
55
default 0;
66
'~Opera Mini' 1;
77
}
8+
9+
charset_map koi8-r utf-8 {
10+
C0 D18E;
11+
C1 D0B0;
12+
}
813
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
events {
2+
}
3+
http {
4+
map $http_user_agent $mobile {
5+
default 0;
6+
'~Opera Mini' 1;
7+
i_am_lost {
8+
return 500;
9+
}
10+
too many params;
11+
}
12+
13+
charset_map koi8-r utf-8 {
14+
C0;
15+
}
16+
}

0 commit comments

Comments
 (0)