Skip to content

Commit

Permalink
Make rangeConsent and rangeException struct types (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
joewreschnig authored Aug 5, 2021
1 parent 44e39b4 commit 465610b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 72 deletions.
52 changes: 20 additions & 32 deletions vendorconsent/tcf1/rangesection.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ func parseRangeSection(data consentMetadata) (*rangeSection, error) {
// Parse out the "exceptions" here.
currentOffset := uint(186)
exceptions := make([]rangeException, numEntries)
for i := uint16(0); i < numEntries; i++ {
thisException, bitsConsumed, err := parseException(data, currentOffset)
for i := range exceptions {
bitsConsumed, err := parseException(&exceptions[i], data, currentOffset)
if err != nil {
return nil, err
}
exceptions[i] = thisException
currentOffset = currentOffset + bitsConsumed
}

Expand All @@ -45,46 +44,47 @@ func parseNumEntries(data []byte) uint16 {
// RangeSection Exception implemnetations

// parseException parses a RangeSection exception starting from the initial bit.
// It returns the exception, as well as the number of bits consumed by the parsing.
func parseException(data consentMetadata, initialBit uint) (rangeException, uint, error) {
// It returns the number of bits consumed by the parsing.
func parseException(dst *rangeException, data consentMetadata, initialBit uint) (uint, error) {
// Fixes #10
if uint(len(data)) <= initialBit/8 {
return nil, 0, fmt.Errorf("bit %d was supposed to start a new RangeEntry, but the consent string was only %d bytes long", initialBit, len(data))
return 0, fmt.Errorf("bit %d was supposed to start a new RangeEntry, but the consent string was only %d bytes long", initialBit, len(data))
}
// If the first bit is set, it's a Range of IDs
if isSet(data, initialBit) {
start, err := parseUInt16(data, initialBit+1)
if err != nil {
return nil, 0, err
return 0, err
}
end, err := parseUInt16(data, initialBit+17)
if err != nil {
return nil, 0, err
return 0, err
}
if start == 0 {
return nil, 0, fmt.Errorf("bit %d range entry exclusion starts at 0, but the min vendor ID is 1", initialBit)
return 0, fmt.Errorf("bit %d range entry exclusion starts at 0, but the min vendor ID is 1", initialBit)
}
if end > data.MaxVendorID() {
return nil, 0, fmt.Errorf("bit %d range entry exclusion ends at %d, but the max vendor ID is %d", initialBit, end, data.MaxVendorID())
return 0, fmt.Errorf("bit %d range entry exclusion ends at %d, but the max vendor ID is %d", initialBit, end, data.MaxVendorID())
}
if end <= start {
return nil, 0, fmt.Errorf("bit %d range entry excludes vendors [%d, %d]. The start should be less than the end", initialBit, start, end)
return 0, fmt.Errorf("bit %d range entry excludes vendors [%d, %d]. The start should be less than the end", initialBit, start, end)
}
return rangeVendorException{
startID: start,
endID: end,
}, uint(33), nil
dst.startID = start
dst.endID = end
return 33, nil
}

vendorID, err := parseUInt16(data, initialBit+1)
if err != nil {
return nil, 0, err
return 0, err
}
if vendorID == 0 || vendorID > data.MaxVendorID() {
return nil, 0, fmt.Errorf("bit %d range entry excludes vendor %d, but only vendors [1, %d] are valid", initialBit, vendorID, data.MaxVendorID())
return 0, fmt.Errorf("bit %d range entry excludes vendor %d, but only vendors [1, %d] are valid", initialBit, vendorID, data.MaxVendorID())
}

return singleVendorException(vendorID), 17, nil
dst.startID = vendorID
dst.endID = vendorID
return 17, nil
}

// parseUInt16 parses a 16-bit integer from the data array, starting at the given index
Expand Down Expand Up @@ -135,25 +135,13 @@ func (p rangeSection) VendorConsent(id uint16) bool { // TODO check if possible
return p.defaultValue
}

// A RangeSection has a default consent value and a list of "exceptions". This represents an "exception" blob
type rangeException interface {
Contains(id uint16) bool
}

// This is a RangeSection exception for a single vendor.
type singleVendorException uint16

func (e singleVendorException) Contains(id uint16) bool {
return uint16(e) == id
}

// This is a RangeSection exception for a range of IDs.
// The start and end bounds here are inclusive.
type rangeVendorException struct {
type rangeException struct {
startID uint16
endID uint16
}

func (e rangeVendorException) Contains(id uint16) bool { // TODO check if possible convert to pointer receiver
func (e rangeException) Contains(id uint16) bool {
return e.startID <= id && e.endID >= id
}
5 changes: 2 additions & 3 deletions vendorconsent/tcf2/pubrestrict.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@ func parsePubRestriction(metadata ConsentMetadata, startbit uint) (*pubRestricti
}
currentOffset = currentOffset + 12
vendors := make([]rangeConsent, numEntries)
for i := uint16(0); i < numEntries; i++ {
thisConsent, bitsConsumed, err := parseRangeConsent(data, currentOffset, assumedMaxVendorID)
for i := range vendors {
bitsConsumed, err := parseRangeConsent(&vendors[i], data, currentOffset, assumedMaxVendorID)
if err != nil {
return nil, 0, err
}
vendors[i] = thisConsent
currentOffset = currentOffset + bitsConsumed
}
restrictions[restrictData] = pubRestriction{
Expand Down
60 changes: 23 additions & 37 deletions vendorconsent/tcf2/rangesection.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,70 +22,68 @@ func parseRangeSection(metadata ConsentMetadata, maxVendorID uint16, startbit ui
// Parse out the "exceptions" here.
currentOffset := startbit + 12
consents := make([]rangeConsent, numEntries)
for i := uint16(0); i < numEntries; i++ {
thisConsent, bitsConsumed, err := parseRangeConsent(data, currentOffset, maxVendorID)
for i := range consents {
bitsConsumed, err := parseRangeConsent(&consents[i], data, currentOffset, maxVendorID)
if err != nil {
return nil, 0, err
}
consents[i] = thisConsent
currentOffset = currentOffset + bitsConsumed
}

return &rangeSection{
consentData: data,
consents: consents,
maxVendorID: maxVendorID,
}, currentOffset, nil
}

// RangeSection Exception implemnetations
// RangeSection Exception implementations

// parseRangeConsents parses a RangeSection starting from the initial bit.
// It returns the exception, as well as the number of bits consumed by the parsing.
func parseRangeConsent(data []byte, initialBit uint, maxVendorID uint16) (rangeConsent, uint, error) {
// It returns the number of bits consumed by the parsing.
func parseRangeConsent(dst *rangeConsent, data []byte, initialBit uint, maxVendorID uint16) (uint, error) {
// Fixes #10
if uint(len(data)) <= initialBit/8 {
return nil, 0, fmt.Errorf("bit %d was supposed to start a new RangeEntry, but the consent string was only %d bytes long", initialBit, len(data))
return 0, fmt.Errorf("bit %d was supposed to start a new RangeEntry, but the consent string was only %d bytes long", initialBit, len(data))
}
// If the first bit is set, it's a Range of IDs
if isSet(data, initialBit) {
start, err := bitutils.ParseUInt16(data, initialBit+1)
if err != nil {
return nil, 0, err
return 0, err
}
end, err := bitutils.ParseUInt16(data, initialBit+17)
if err != nil {
return nil, 0, err
return 0, err
}
if start == 0 {
return nil, 0, fmt.Errorf("bit %d range entry exclusion starts at 0, but the min vendor ID is 1", initialBit)
return 0, fmt.Errorf("bit %d range entry exclusion starts at 0, but the min vendor ID is 1", initialBit)
}
if end > maxVendorID {
return nil, 0, fmt.Errorf("bit %d range entry exclusion ends at %d, but the max vendor ID is %d", initialBit, end, maxVendorID)
return 0, fmt.Errorf("bit %d range entry exclusion ends at %d, but the max vendor ID is %d", initialBit, end, maxVendorID)
}
if end <= start {
return nil, 0, fmt.Errorf("bit %d range entry excludes vendors [%d, %d]. The start should be less than the end", initialBit, start, end)
return 0, fmt.Errorf("bit %d range entry excludes vendors [%d, %d]. The start should be less than the end", initialBit, start, end)
}
return rangeVendorConsent{
startID: start,
endID: end,
}, uint(33), nil
dst.startID = start
dst.endID = end
return 33, nil
}

vendorID, err := bitutils.ParseUInt16(data, initialBit+1)
if err != nil {
return nil, 0, err
return 0, err
}
if vendorID == 0 || vendorID > maxVendorID {
return nil, 0, fmt.Errorf("bit %d range entry excludes vendor %d, but only vendors [1, %d] are valid", initialBit, vendorID, maxVendorID)
return 0, fmt.Errorf("bit %d range entry excludes vendor %d, but only vendors [1, %d] are valid", initialBit, vendorID, maxVendorID)
}

return singleVendorConsent(vendorID), 17, nil
dst.startID = vendorID
dst.endID = vendorID
return 17, nil
}

// A RangeConsents encodes consents that have been registered.
type rangeSection struct {
consentData []byte
consents []rangeConsent
maxVendorID uint16
}
Expand All @@ -99,38 +97,26 @@ func (p *rangeSection) MaxVendorID() uint16 {
}

// VendorConsents implementation
func (p rangeSection) VendorConsent(id uint16) bool { // TODO consider convert to pointer receiver
func (p *rangeSection) VendorConsent(id uint16) bool {
if id < 1 || id > p.maxVendorID {
return false
}

for i := 0; i < len(p.consents); i++ {
for i := range p.consents {
if p.consents[i].Contains(id) {
return true
}
}
return false
}

// A RangeSection has a default consent value and a list of "exceptions". This represents an "exception" blob
type rangeConsent interface {
Contains(id uint16) bool
}

// This is a RangeSection exception for a single vendor.
type singleVendorConsent uint16

func (e singleVendorConsent) Contains(id uint16) bool {
return uint16(e) == id
}

// This is a RangeSection exception for a range of IDs.
// The start and end bounds here are inclusive.
type rangeVendorConsent struct {
type rangeConsent struct {
startID uint16
endID uint16
}

func (e rangeVendorConsent) Contains(id uint16) bool { // TODO consider convert to pointer receiver
func (e rangeConsent) Contains(id uint16) bool {
return e.startID <= id && e.endID >= id
}

0 comments on commit 465610b

Please sign in to comment.