...

Source file src/github.com/sassoftware/relic/lib/assuan/csexp.go

Documentation: github.com/sassoftware/relic/lib/assuan

     1  //
     2  // Copyright (c) SAS Institute Inc.
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  // Unless required by applicable law or agreed to in writing, software
    11  // distributed under the License is distributed on an "AS IS" BASIS,
    12  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  // See the License for the specific language governing permissions and
    14  // limitations under the License.
    15  //
    16  
    17  package assuan
    18  
    19  // http://people.csail.mit.edu/rivest/Sexp.txt
    20  
    21  import (
    22  	"bytes"
    23  	"errors"
    24  	"strconv"
    25  )
    26  
    27  type csExp struct {
    28  	Value []byte
    29  	Items []*csExp
    30  }
    31  
    32  var InvalidCsExp = errors.New("invalid cs-exp")
    33  
    34  func parseCsExp(blob []byte) (*csExp, error) {
    35  	root := new(csExp)
    36  	stack := []*csExp{root}
    37  	top := root
    38  csloop:
    39  	for {
    40  		switch {
    41  		case len(blob) == 0:
    42  			if len(stack) > 1 {
    43  				return nil, InvalidCsExp
    44  			}
    45  			break csloop
    46  		case blob[0] == '(':
    47  			item := new(csExp)
    48  			stack = append(stack, item)
    49  			top.Items = append(top.Items, item)
    50  			top = item
    51  			blob = blob[1:]
    52  		case blob[0] == ')':
    53  			if len(stack) < 2 {
    54  				return nil, InvalidCsExp
    55  			}
    56  			stack = stack[:len(stack)-1]
    57  			top = stack[len(stack)-1]
    58  			blob = blob[1:]
    59  		default:
    60  			n := bytes.IndexByte(blob, ':')
    61  			if n < 1 {
    62  				return nil, InvalidCsExp
    63  			}
    64  			length, err := strconv.ParseUint(string(blob[:n]), 10, 64)
    65  			if err != nil || length > uint64(len(blob)-n-1) {
    66  				return nil, InvalidCsExp
    67  			}
    68  			blob = blob[n+1:]
    69  			data := blob[:length]
    70  			blob = blob[length:]
    71  			top.Items = append(top.Items, &csExp{Value: data})
    72  		}
    73  	}
    74  	return root, nil
    75  }
    76  

View as plain text