Skip to content

Commit 08a0863

Browse files
Louis DeLosSantoslouis
andauthored
Add dpkg support (#7)
This PR adds several data structures and memo methods to support parsing dpkginfo oval structures. Signed-off-by: louis <[email protected]> Co-authored-by: louis <[email protected]>
1 parent 1ff8552 commit 08a0863

File tree

7 files changed

+196
-34
lines changed

7 files changed

+196
-34
lines changed

oval/dpkginfo.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package oval
2+
3+
import (
4+
"encoding/xml"
5+
)
6+
7+
// DpkgInfoTest : >tests>dpkginfo_test
8+
type DpkgInfoTest struct {
9+
XMLName xml.Name `xml:"dpkginfo_test"`
10+
ID string `xml:"id,attr"`
11+
Comment string `xml:"comment,attr"`
12+
Check string `xml:"check,attr"`
13+
Version int `xml:"version,attr"`
14+
ObjectRefs []ObjectRef `xml:"object"`
15+
StateRefs []StateRef `xml:"state"`
16+
}
17+
18+
// DpkgName : >objects>dpkginfo_object>name
19+
//
20+
// when parsing ubuntu var_ref is a reference
21+
// to the <variables> section of the document
22+
//
23+
// when parsing debian var_ref is empty and
24+
// the Body field is used directly
25+
type DpkgName struct {
26+
XMLName xml.Name `xml:"name"`
27+
Ref string `xml:"var_ref,attr"`
28+
Body string `xml:",chardata"`
29+
}
30+
31+
// DpkgInfoObject : >objects>dpkginfo_object
32+
type DpkgInfoObject struct {
33+
XMLName xml.Name `xml:"dpkginfo_object"`
34+
ID string `xml:"id,attr"`
35+
Version int `xml:"version,attr"`
36+
Name *DpkgName `xml:"name"`
37+
}
38+
39+
// DpkgInfoState : >states>dpkginfo_state
40+
type DpkgInfoState struct {
41+
XMLName xml.Name `xml:"dpkginfo_state"`
42+
ID string `xml:"id,attr"`
43+
Version int `xml:"version,attr"`
44+
Arch *Arch `xml:"arch"`
45+
Epoch *Epoch `xml:"epoch"`
46+
Release *Release `xml:"release"`
47+
DpkgVersion *Version `xml:"version"`
48+
EVR *EVR `xml:"evr"`
49+
}

oval/objects.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77

88
func (o *Objects) init() {
99
var wg sync.WaitGroup
10-
wg.Add(3)
10+
wg.Add(4)
1111

1212
go func() {
1313
defer wg.Done()
@@ -33,6 +33,14 @@ func (o *Objects) init() {
3333
}
3434
}()
3535

36+
go func() {
37+
defer wg.Done()
38+
o.dpkginfoMemo = make(map[string]int, len(o.DpkgInfoObjects))
39+
for i, v := range o.DpkgInfoObjects {
40+
o.dpkginfoMemo[v.ID] = i
41+
}
42+
}()
43+
3644
wg.Wait()
3745
}
3846

@@ -43,13 +51,15 @@ func (o *Objects) Lookup(ref string) (kind string, index int, err error) {
4351
if i, ok := o.lineMemo[ref]; ok {
4452
return o.LineObjects[i].XMLName.Local, i, nil
4553
}
46-
4754
if i, ok := o.version55Memo[ref]; ok {
4855
return o.Version55Objects[i].XMLName.Local, i, nil
4956
}
5057
if i, ok := o.rpminfoMemo[ref]; ok {
5158
return o.RPMInfoObjects[i].XMLName.Local, i, nil
5259
}
60+
if i, ok := o.dpkginfoMemo[ref]; ok {
61+
return o.DpkgInfoObjects[i].XMLName.Local, i, nil
62+
}
5363

5464
// We didn't find it, maybe we can say why.
5565
id, err := ParseID(ref)

oval/rpminfo.go

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -39,39 +39,14 @@ type RPMInfoState struct {
3939
XMLName xml.Name `xml:"rpminfo_state"`
4040
ID string `xml:"id,attr"`
4141
Version int `xml:"version,attr"`
42-
Arch *RPMArch `xml:"arch"`
43-
Epoch *RPMEpoch `xml:"epoch"`
44-
Release *RPMRelease `xml:"release"`
45-
RPMVersion *RPMVersion `xml:"version"`
46-
EVR *RPMEVR `xml:"evr"`
42+
Arch *Arch `xml:"arch"`
43+
Epoch *Epoch `xml:"epoch"`
44+
Release *Release `xml:"release"`
45+
RPMVersion *Version `xml:"version"`
46+
EVR *EVR `xml:"evr"`
4747
SignatureKeyID *RPMSignatureKeyID `xml:"signature_keyid"`
4848
}
4949

50-
type RPMArch struct {
51-
XMLName xml.Name `xml:"arch"`
52-
Operation Operation `xml:"operation,attr"`
53-
Body string `xml:",chardata"`
54-
}
55-
type RPMEpoch struct {
56-
XMLName xml.Name `xml:"epoch"`
57-
Operation Operation `xml:"operation,attr"`
58-
Body string `xml:",chardata"`
59-
}
60-
type RPMRelease struct {
61-
XMLName xml.Name `xml:"release"`
62-
Operation Operation `xml:"operation,attr"`
63-
Body string `xml:",chardata"`
64-
}
65-
type RPMVersion struct {
66-
XMLName xml.Name `xml:"version"`
67-
Operation Operation `xml:"operation,attr"`
68-
Body string `xml:",chardata"`
69-
}
70-
type RPMEVR struct {
71-
XMLName xml.Name `xml:"evr"`
72-
Operation Operation `xml:"operation,attr"`
73-
Body string `xml:",chardata"`
74-
}
7550
type RPMSignatureKeyID struct {
7651
XMLName xml.Name `xml:"signature_keyid"`
7752
Operation Operation `xml:"operation,attr"`

oval/states.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77

88
func (s *States) init() {
99
var wg sync.WaitGroup
10-
wg.Add(3)
10+
wg.Add(4)
1111

1212
go func() {
1313
defer wg.Done()
@@ -33,6 +33,14 @@ func (s *States) init() {
3333
}
3434
}()
3535

36+
go func() {
37+
defer wg.Done()
38+
s.dpkginfoMemo = make(map[string]int, len(s.DpkgInfoStates))
39+
for i, v := range s.DpkgInfoStates {
40+
s.dpkginfoMemo[v.ID] = i
41+
}
42+
}()
43+
3644
wg.Wait()
3745
}
3846

@@ -50,6 +58,9 @@ func (s *States) Lookup(ref string) (kind string, index int, err error) {
5058
if i, ok := s.rpminfoMemo[ref]; ok {
5159
return s.RPMInfoStates[i].XMLName.Local, i, nil
5260
}
61+
if i, ok := s.dpkginfoMemo[ref]; ok {
62+
return s.DpkgInfoStates[i].XMLName.Local, i, nil
63+
}
5364

5465
// We didn't find it, maybe we can say why.
5566
id, err := ParseID(ref)

oval/tests.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
// Init sets up the memoization maps.
99
func (t *Tests) init() {
1010
var wg sync.WaitGroup
11-
wg.Add(6)
11+
wg.Add(7)
1212

1313
go func() {
1414
defer wg.Done()
@@ -34,6 +34,14 @@ func (t *Tests) init() {
3434
}
3535
}()
3636

37+
go func() {
38+
defer wg.Done()
39+
t.dpkginfoMemo = make(map[string]int, len(t.DpkgInfoTests))
40+
for i, v := range t.DpkgInfoTests {
41+
t.dpkginfoMemo[v.ID] = i
42+
}
43+
}()
44+
3745
go func() {
3846
defer wg.Done()
3947
t.rpmverifyfileMemo = make(map[string]int, len(t.RPMVerifyFileTests))
@@ -76,6 +84,9 @@ func (t *Tests) Lookup(ref string) (kind string, index int, err error) {
7684
if i, ok := t.rpminfoMemo[ref]; ok {
7785
return t.RPMInfoTests[i].XMLName.Local, i, nil
7886
}
87+
if i, ok := t.dpkginfoMemo[ref]; ok {
88+
return t.DpkgInfoTests[i].XMLName.Local, i, nil
89+
}
7990
if i, ok := t.rpmverifyfileMemo[ref]; ok {
8091
return t.RPMVerifyFileTests[i].XMLName.Local, i, nil
8192
}

oval/types.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type Root struct {
2323
Tests Tests `xml:"tests"`
2424
Objects Objects `xml:"objects"`
2525
States States `xml:"states"`
26+
Variables Variables `xml:"variables"`
2627
}
2728

2829
// Generator : >generator
@@ -229,12 +230,14 @@ type Tests struct {
229230
LineTests []LineTest `xml:"line_test"`
230231
Version55Tests []Version55Test `xml:"version55_test"`
231232
RPMInfoTests []RPMInfoTest `xml:"rpminfo_test"`
233+
DpkgInfoTests []DpkgInfoTest `xml:"dpkginfo_test"`
232234
RPMVerifyFileTests []RPMVerifyFileTest `xml:"rpmverifyfile_test"`
233235
UnameTests []UnameTest `xml:"uname_test"`
234236
TextfileContent54Tests []TextfileContent54Test `xml:"textfilecontent54_test"`
235237
lineMemo map[string]int
236238
version55Memo map[string]int
237239
rpminfoMemo map[string]int
240+
dpkginfoMemo map[string]int
238241
rpmverifyfileMemo map[string]int
239242
unameMemo map[string]int
240243
textfilecontent54Memo map[string]int
@@ -261,9 +264,11 @@ type Objects struct {
261264
LineObjects []LineObject `xml:"line_object"`
262265
Version55Objects []Version55Object `xml:"version55_object"`
263266
RPMInfoObjects []RPMInfoObject `xml:"rpminfo_object"`
267+
DpkgInfoObjects []DpkgInfoObject `xml:"dpkginfo_object"`
264268
lineMemo map[string]int
265269
version55Memo map[string]int
266270
rpminfoMemo map[string]int
271+
dpkginfoMemo map[string]int
267272
}
268273

269274
// States : >states
@@ -273,7 +278,68 @@ type States struct {
273278
LineStates []LineState `xml:"line_state"`
274279
Version55States []Version55State `xml:"version55_state"`
275280
RPMInfoStates []RPMInfoState `xml:"rpminfo_state"`
281+
DpkgInfoStates []DpkgInfoState `xml:"dpkginfo_state"`
276282
lineMemo map[string]int
277283
version55Memo map[string]int
278284
rpminfoMemo map[string]int
285+
dpkginfoMemo map[string]int
286+
}
287+
288+
// Value
289+
type Value struct {
290+
XMLName xml.Name `xml:"value"`
291+
Body string `xml:",chardata"`
292+
}
293+
294+
// ConstantVariable
295+
type ConstantVariable struct {
296+
XMLName xml.Name `xml:"constant_variable"`
297+
ID string `xml:"id,attr"`
298+
Version string `xml:"version,attr"`
299+
Datatype string `xml:"datatype,attr"`
300+
Comment string `xml:"comment,attr"`
301+
Values []Value `xml:"value"`
302+
}
303+
304+
// Variables : >variables
305+
type Variables struct {
306+
once sync.Once
307+
XMLName xml.Name `xml:"variables"`
308+
ConstantVariables []ConstantVariable `xml:"constant_variable"`
309+
dpkginfoMemo map[string]int
310+
}
311+
312+
// Arch
313+
type Arch struct {
314+
XMLName xml.Name `xml:"arch"`
315+
Operation Operation `xml:"operation,attr"`
316+
Body string `xml:",chardata"`
317+
}
318+
319+
// Epoch
320+
type Epoch struct {
321+
XMLName xml.Name `xml:"epoch"`
322+
Operation Operation `xml:"operation,attr"`
323+
Body string `xml:",chardata"`
324+
}
325+
326+
// Release
327+
type Release struct {
328+
XMLName xml.Name `xml:"release"`
329+
Operation Operation `xml:"operation,attr"`
330+
Body string `xml:",chardata"`
331+
}
332+
333+
// Version
334+
type Version struct {
335+
XMLName xml.Name `xml:"version"`
336+
Operation Operation `xml:"operation,attr"`
337+
Body string `xml:",chardata"`
338+
}
339+
340+
// EVR
341+
type EVR struct {
342+
XMLName xml.Name `xml:"evr"`
343+
Operation Operation `xml:"operation,attr"`
344+
Body string `xml:",chardata"`
279345
}

oval/variables.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package oval
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
func (o *Variables) init() {
9+
var wg sync.WaitGroup
10+
wg.Add(1)
11+
12+
go func() {
13+
defer wg.Done()
14+
o.dpkginfoMemo = make(map[string]int, len(o.ConstantVariables))
15+
for i, v := range o.ConstantVariables {
16+
o.dpkginfoMemo[v.ID] = i
17+
}
18+
}()
19+
20+
wg.Wait()
21+
}
22+
23+
// Lookup returns the kind of object and index into that kind-specific slice, if
24+
// found.
25+
func (o *Variables) Lookup(ref string) (kind string, index int, err error) {
26+
o.once.Do(o.init)
27+
if i, ok := o.dpkginfoMemo[ref]; ok {
28+
return o.ConstantVariables[i].XMLName.Local, i, nil
29+
}
30+
31+
// We didn't find it, maybe we can say why.
32+
id, err := ParseID(ref)
33+
if err != nil {
34+
return "", -1, err
35+
}
36+
if id.Type != OvalVariable {
37+
return "", -1, fmt.Errorf("oval: wrong identifier type %q", id.Type)
38+
}
39+
return "", -1, ErrNotFound(ref)
40+
}

0 commit comments

Comments
 (0)