NullifyProtoField removes a field from protobytes without unmarshalling
(protoBytes []byte, fieldNumber int)
| 112 | |
| 113 | // NullifyProtoField removes a field from protobytes without unmarshalling |
| 114 | func NullifyProtoField(protoBytes []byte, fieldNumber int) ([]byte, error) { |
| 115 | var offset int |
| 116 | // create a buffer to store the result |
| 117 | result := make([]byte, 0, len(protoBytes)) |
| 118 | // iterate through the bytes |
| 119 | for offset < len(protoBytes) { |
| 120 | // remember the start position of this field |
| 121 | fieldStart := offset |
| 122 | // decode the field tag |
| 123 | fieldNum, wireType, tagLen := protowire.ConsumeTag(protoBytes[offset:]) |
| 124 | if tagLen < 0 { |
| 125 | return nil, fmt.Errorf("invalid tag at offset %d", offset) |
| 126 | } |
| 127 | // update the offset |
| 128 | offset += tagLen |
| 129 | // calculate the field value length |
| 130 | valueLen := protowire.ConsumeFieldValue(fieldNum, wireType, protoBytes[offset:]) |
| 131 | if valueLen < 0 { |
| 132 | return nil, fmt.Errorf("invalid field value at offset %d", offset) |
| 133 | } |
| 134 | // if this is the field to nullify, skip it entirely |
| 135 | if int(fieldNum) == fieldNumber { |
| 136 | offset += valueLen |
| 137 | continue |
| 138 | } |
| 139 | // for all other fields, copy them to the result |
| 140 | fieldEnd := offset + valueLen |
| 141 | // copy to the result |
| 142 | result = append(result, protoBytes[fieldStart:fieldEnd]...) |
| 143 | // update the offset |
| 144 | offset = fieldEnd |
| 145 | } |
| 146 | // return the result |
| 147 | return result, nil |
| 148 | } |
no test coverage detected