-
Notifications
You must be signed in to change notification settings - Fork 15
/
analyze_map.go
105 lines (94 loc) · 2.86 KB
/
analyze_map.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* Copyright (c) F5, Inc.
*
* This source code is licensed under the Apache License, Version 2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
package crossplane
import "fmt"
// mapParameterMasks holds bit masks that define the behavior of the body of map-like directives.
// Some map directives have "special parameter" with different behaviors than the default.
type mapParameterMasks struct {
specialParameterMasks map[string]uint
defaultMasks uint
}
//nolint:gochecknoglobals
var mapBodies = map[string]mapParameterMasks{
"charset_map": {
defaultMasks: ngxConfTake1,
},
"geo": {
specialParameterMasks: map[string]uint{"ranges": ngxConfNoArgs, "proxy_recursive": ngxConfNoArgs},
defaultMasks: ngxConfTake1,
},
"map": {
specialParameterMasks: map[string]uint{"volatile": ngxConfNoArgs, "hostnames": ngxConfNoArgs},
defaultMasks: ngxConfTake1,
},
"match": {
defaultMasks: ngxConf1More,
},
"types": {
defaultMasks: ngxConf1More,
},
"split_clients": {
defaultMasks: ngxConfTake1,
},
"geoip2": {
specialParameterMasks: map[string]uint{"auto_reload": ngxConfTake1},
defaultMasks: ngxConf1More,
},
"otel_exporter": {
defaultMasks: ngxConfTake1,
},
}
// analyzeMapBody validates the body of a map-like directive. Map-like directives are block directives
// that don't contain nginx directives, and therefore cannot be analyzed in the same way as other blocks.
func analyzeMapBody(fname string, parameter *Directive, term string, mapCtx string) error {
masks, known := mapBodies[mapCtx]
// if we're not inside a known map-like directive, don't bother analyzing
if !known {
return nil
}
if term != ";" {
return &ParseError{
What: fmt.Sprintf(`unexpected "%s"`, term),
File: &fname,
Line: ¶meter.Line,
Statement: parameter.String(),
BlockCtx: mapCtx,
}
}
if mask, ok := masks.specialParameterMasks[parameter.Directive]; ok {
// use mask to check the parameter's arguments
if hasValidArguments(mask, parameter.Args) {
return nil
}
return &ParseError{
What: "invalid number of parameters",
File: &fname,
Line: ¶meter.Line,
Statement: parameter.String(),
BlockCtx: mapCtx,
}
}
mask := masks.defaultMasks
// use mask to check the parameter's arguments
if hasValidArguments(mask, parameter.Args) {
return nil
}
return &ParseError{
What: "invalid number of parameters",
File: &fname,
Line: ¶meter.Line,
Statement: parameter.String(),
BlockCtx: mapCtx,
}
}
func hasValidArguments(mask uint, args []string) bool {
return ((mask>>len(args)&1) != 0 && len(args) <= 7) || // NOARGS to TAKE7
((mask&ngxConfFlag) != 0 && len(args) == 1 && validFlag(args[0])) ||
((mask & ngxConfAny) != 0) ||
((mask&ngxConf1More) != 0 && len(args) >= 1) ||
((mask&ngxConf2More) != 0 && len(args) >= 2)
}