Skip to content

Commit 0ddea4d

Browse files
committed
Bugs in determining the validity of Level and Layout have been fixed
1 parent fc60626 commit 0ddea4d

File tree

2 files changed

+78
-42
lines changed

2 files changed

+78
-42
lines changed

layout/layout.go

+58-40
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const (
2929

3030
// The overflowLayoutValue is a exceeding the limit of permissible
3131
// values for the Layout.
32-
overflowLayoutValue Layout = (1 << iota) - 1
32+
overflowLayoutValue Layout = (1 << iota)
3333

3434
// Default is the default format for the log message.
3535
Default = ShortFilePath | FuncName | LineNumber
@@ -41,40 +41,58 @@ type Layout uint8
4141
// IsSingle returns true if value contains single of the available flag.
4242
// The custom flags cannot be valid since they should not affect the
4343
// formatting settings. The zero value is an invalid flag too.
44-
func (f *Layout) IsSingle() bool {
45-
return bits.OnesCount(uint(*f)) == 1 &&
46-
*f <= Layout(overflowLayoutValue+1)>>1
44+
func (l *Layout) IsSingle() bool {
45+
return bits.OnesCount(uint(*l)) == 1 &&
46+
*l <= Layout(overflowLayoutValue+1)>>1
4747
}
4848

4949
// Contains method returns true if value contains the specified flag.
5050
// Returns false and an error if the value is invalid or an
5151
// invalid flag is specified.
52-
func (f *Layout) Contains(flag Layout) (bool, error) {
52+
func (l *Layout) Contains(flag Layout) (bool, error) {
5353
switch {
5454
case !flag.IsValid():
5555
return false, errors.New("incorrect flag value")
56-
case !f.IsValid():
56+
case !l.IsValid():
5757
return false, errors.New("the object is damaged")
5858
}
5959

60-
return *f&Layout(flag) == Layout(flag), nil
60+
return *l&Layout(flag) == Layout(flag), nil
6161
}
6262

6363
// IsValid returns true if value contains zero, one or an
6464
// unique sum of valid FormatFlag flags. The zero value is a valid value.
65-
func (f *Layout) IsValid() bool {
66-
return *f <= overflowLayoutValue
65+
func (l *Layout) IsValid() bool {
66+
// Check if object is zero, which is a valid value.
67+
if *l == 0 {
68+
return true
69+
}
70+
71+
copy := *l
72+
// Iterate over all possible values of the constants and
73+
// check whether they are part of object.
74+
for layout := Layout(1); layout < overflowLayoutValue; layout <<= 1 {
75+
// If layout is part of the object, remove it from object.
76+
if copy&layout == layout {
77+
copy ^= layout
78+
}
79+
}
80+
81+
// Check whether all bits of t were "turned off".
82+
// If t is zero, it means that all bits were matched values
83+
// of constants, and therefore t is valid.
84+
return copy == 0
6785
}
6886

6987
// FilePath returns true if value contains the FullPath or ShortPath flags.
7088
// Returns false and an error if the value is invalid.
71-
func (f *Layout) FilePath() bool {
72-
ffp, err := f.Contains(FullFilePath)
89+
func (l *Layout) FilePath() bool {
90+
ffp, err := l.Contains(FullFilePath)
7391
if err == nil && ffp {
7492
return true
7593
}
7694

77-
sfp, err := f.Contains(ShortFilePath)
95+
sfp, err := l.Contains(ShortFilePath)
7896
if err == nil && sfp {
7997
return true
8098
}
@@ -83,100 +101,100 @@ func (f *Layout) FilePath() bool {
83101
}
84102

85103
// FullFilePath returns true if value contains the FullPath flag.
86-
func (f *Layout) FullFilePath() bool {
87-
v, _ := f.Contains(FullFilePath)
104+
func (l *Layout) FullFilePath() bool {
105+
v, _ := l.Contains(FullFilePath)
88106
return v
89107
}
90108

91109
// ShortFilePath returns true if value contains the ShortPath flag.
92-
func (f *Layout) ShortFilePath() bool {
93-
v, _ := f.Contains(ShortFilePath)
110+
func (l *Layout) ShortFilePath() bool {
111+
v, _ := l.Contains(ShortFilePath)
94112
return v
95113
}
96114

97115
// FuncName returns true if value contains the FuncName flag.
98-
func (f *Layout) FuncName() bool {
99-
v, _ := f.Contains(FuncName)
116+
func (l *Layout) FuncName() bool {
117+
v, _ := l.Contains(FuncName)
100118
return v
101119
}
102120

103121
// FuncAddress returns true if value contains the FuncAddress flag.
104-
func (f *Layout) FuncAddress() bool {
105-
v, _ := f.Contains(FuncAddress)
122+
func (l *Layout) FuncAddress() bool {
123+
v, _ := l.Contains(FuncAddress)
106124
return v
107125
}
108126

109127
// LineNumber returns true if value contains the LineNumber flag.
110-
func (f *Layout) LineNumber() bool {
111-
v, _ := f.Contains(LineNumber)
128+
func (l *Layout) LineNumber() bool {
129+
v, _ := l.Contains(LineNumber)
112130
return v
113131
}
114132

115133
// Set sets the specified flags ignores duplicates.
116134
// The flags that were set previously will be discarded.
117135
// Returns a new value if all is well or old value and an
118136
// error if one or more invalid flags are specified.
119-
func (f *Layout) Set(flags ...Layout) (Layout, error) {
137+
func (l *Layout) Set(flags ...Layout) (Layout, error) {
120138
var r Layout
121139

122140
for _, flag := range flags {
123141
if !flag.IsValid() {
124-
return *f, fmt.Errorf("the %d is invalid flag value", flag)
142+
return *l, fmt.Errorf("the %d is invalid flag value", flag)
125143
}
126144

127145
if ok, _ := r.Contains(flag); !ok {
128146
r += Layout(flag)
129147
}
130148
}
131149

132-
*f = r
133-
return *f, nil
150+
*l = r
151+
return *l, nil
134152
}
135153

136154
// Add adds the specified flags ignores duplicates or flags that value
137155
// already contains. Returns a new value if all is well or old value and
138156
// an error if one or more invalid flags are specified.
139-
func (f *Layout) Add(flags ...Layout) (Layout, error) {
140-
r := *f
157+
func (l *Layout) Add(flags ...Layout) (Layout, error) {
158+
r := *l
141159

142160
for _, flag := range flags {
143161
if !flag.IsValid() {
144-
return *f, fmt.Errorf("the %d is invalid flag value", flag)
162+
return *l, fmt.Errorf("the %d is invalid flag value", flag)
145163
}
146164

147165
if ok, _ := r.Contains(flag); !ok {
148166
r += Layout(flag)
149167
}
150168
}
151169

152-
*f = r
153-
return *f, nil
170+
*l = r
171+
return *l, nil
154172
}
155173

156174
// Delete deletes the specified flags ignores duplicates or
157175
// flags that were not set. Returns a new value if all is well or
158176
// old value and an error if one or more invalid flags are specified.
159-
func (f *Layout) Delete(flags ...Layout) (Layout, error) {
160-
r := *f
177+
func (l *Layout) Delete(flags ...Layout) (Layout, error) {
178+
r := *l
161179

162180
for _, flag := range flags {
163181
if !flag.IsValid() {
164-
return *f, fmt.Errorf("the %d is invalid flag value", flag)
182+
return *l, fmt.Errorf("the %d is invalid flag value", flag)
165183
}
166184

167185
if ok, _ := r.Contains(flag); ok {
168186
r -= Layout(flag)
169187
}
170188
}
171189

172-
*f = r
173-
return *f, nil
190+
*l = r
191+
return *l, nil
174192
}
175193

176194
// All returns true if all of the specified flags are set.
177-
func (f *Layout) All(flags ...Layout) bool {
195+
func (l *Layout) All(flags ...Layout) bool {
178196
for _, flag := range flags {
179-
if ok, _ := f.Contains(flag); !ok {
197+
if ok, _ := l.Contains(flag); !ok {
180198
return false
181199
}
182200
}
@@ -185,9 +203,9 @@ func (f *Layout) All(flags ...Layout) bool {
185203
}
186204

187205
// Any returns true if at least one of the specified flags is set.
188-
func (f *Layout) Any(flags ...Layout) bool {
206+
func (l *Layout) Any(flags ...Layout) bool {
189207
for _, flag := range flags {
190-
if ok, _ := f.Contains(flag); ok {
208+
if ok, _ := l.Contains(flag); ok {
191209
return true
192210
}
193211
}

level/level.go

+20-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const (
3030

3131
// The overflowLevelValue is a exceeding the limit of permissible
3232
// values for the Level.
33-
overflowLevelValue Level = (1 << iota) - 1
33+
overflowLevelValue Level = (1 << iota)
3434

3535
// Default is the default logging level.
3636
Default = Panic | Fatal | Error | Warn | Info | Debug | Trace
@@ -85,7 +85,25 @@ func (l *Level) Contains(flag Level) (bool, error) {
8585
// IsValid returns true if value contains zero, one or an
8686
// unique sum of valid LevelFlag flags. The zero value is a valid value.
8787
func (l *Level) IsValid() bool {
88-
return *l <= overflowLevelValue
88+
// Check if object is zero, which is a valid value.
89+
if *l == 0 {
90+
return true
91+
}
92+
93+
copy := *l
94+
// Iterate over all possible values of the constants and
95+
// check whether they are part of object.
96+
for level := Level(1); level < overflowLevelValue; level <<= 1 {
97+
// If layout is part of the object, remove it from object.
98+
if copy&level == level {
99+
copy ^= level
100+
}
101+
}
102+
103+
// Check whether all bits of t were "turned off".
104+
// If t is zero, it means that all bits were matched values
105+
// of constants, and therefore t is valid.
106+
return copy == 0
89107
}
90108

91109
// Panic returns true if value contains the Panic flag.

0 commit comments

Comments
 (0)