github.com/CycloneDX/sbom-utility@v0.16.0/schema/bom_query.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * Licensed to the Apache Software Foundation (ASF) under one or more 4 * contributor license agreements. See the NOTICE file distributed with 5 * this work for additional information regarding copyright ownership. 6 * The ASF licenses this file to You under the Apache License, Version 2.0 7 * (the "License"); you may not use this file except in compliance with 8 * the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package schema 20 21 import ( 22 "bytes" 23 "encoding/gob" 24 "strconv" 25 26 "github.com/CycloneDX/sbom-utility/common" 27 ) 28 29 // Note: Golang supports the RE2 regular exp. engine which does not support many 30 // features such as lookahead, lookbehind, etc. 31 // See: https://en.wikipedia.org/wiki/Comparison_of_regular_expression_engines 32 func whereFilterMatch(mapObject map[string]interface{}, whereFilters []common.WhereFilter) (match bool, err error) { 33 var buf bytes.Buffer 34 var key string 35 36 // create a byte encoder 37 enc := gob.NewEncoder(&buf) 38 39 for _, filter := range whereFilters { 40 41 key = filter.Key 42 value, present := mapObject[key] 43 getLogger().Debugf("testing object map[%s]: `%v`", key, value) 44 45 if !present { 46 match = false 47 err = getLogger().Errorf("key `%s` not found ib object map", key) 48 break 49 } 50 51 // Reset the encoder'a byte buffer on each iteration and 52 // convert the value (an interface{}) to []byte we can use on regex. eval. 53 buf.Reset() 54 55 // Do not encode nil pointer values; replace with empty string 56 if value == nil { 57 value = "" 58 } 59 60 // Handle non-string data types in the map by converting them to string 61 switch data := value.(type) { 62 case string: 63 value = data 64 case bool: 65 value = strconv.FormatBool(data) 66 case int: 67 value = strconv.Itoa(data) 68 case float64: 69 // NOTE: JSON Unmarshal() always decodes JSON Numbers as "float64" type 70 value = strconv.FormatFloat(data, 'f', -1, 64) 71 default: 72 getLogger().Errorf("unhandled datatype. key=%s, value=`%v`, type=`%T`", key, data, data) 73 } 74 75 err = enc.Encode(value) 76 77 if err != nil { 78 err = getLogger().Errorf("Unable to convert value: `%v`, to []byte", value) 79 return 80 } 81 82 // Test that the field value matches the regex supplied in the current filter 83 // Note: the regex compilation is performed during command param. processing 84 if match = filter.ValueRegEx.Match(buf.Bytes()); !match { 85 break 86 } 87 } 88 89 return 90 }