SYS-REQ-112
(data []byte, offset int, open byte)
| 2067 | |
| 2068 | // SYS-REQ-112 |
| 2069 | func scanContainerLen(data []byte, offset int, open byte) (int, error) { |
| 2070 | const ( |
| 2071 | scanArrayValue = iota |
| 2072 | scanArrayPrimitive |
| 2073 | scanArrayDelimiter |
| 2074 | scanObjectKey |
| 2075 | scanObjectColon |
| 2076 | scanObjectValue |
| 2077 | scanObjectPrimitive |
| 2078 | scanObjectDelimiter |
| 2079 | ) |
| 2080 | |
| 2081 | close := byte(']') |
| 2082 | malformedErr := MalformedArrayError |
| 2083 | state := scanArrayValue |
| 2084 | if open == '{' { |
| 2085 | close = '}' |
| 2086 | malformedErr = MalformedObjectError |
| 2087 | state = scanObjectKey |
| 2088 | } |
| 2089 | |
| 2090 | var fixedStack [32]byte |
| 2091 | stack := fixedStack[:1] |
| 2092 | stack[0] = close |
| 2093 | |
| 2094 | count := 0 |
| 2095 | primitiveStart := -1 |
| 2096 | |
| 2097 | for i := offset + 1; i < len(data); i++ { |
| 2098 | c := data[i] |
| 2099 | |
| 2100 | // Only delimiters at the addressed container's top level affect its |
| 2101 | // length. Strings and nested containers are skipped structurally. |
| 2102 | if len(stack) > 1 { |
| 2103 | switch c { |
| 2104 | case '"': |
| 2105 | stringLength, _ := stringEnd(data[i+1:]) |
| 2106 | if stringLength == -1 { |
| 2107 | return 0, malformedErr |
| 2108 | } |
| 2109 | i += stringLength |
| 2110 | case '[': |
| 2111 | stack = append(stack, ']') |
| 2112 | case '{': |
| 2113 | stack = append(stack, '}') |
| 2114 | case ']', '}': |
| 2115 | if c != stack[len(stack)-1] { |
| 2116 | return 0, malformedErr |
| 2117 | } |
| 2118 | stack = stack[:len(stack)-1] |
| 2119 | } |
| 2120 | continue |
| 2121 | } |
| 2122 | |
| 2123 | switch state { |
| 2124 | case scanArrayValue: |
| 2125 | if isContainerWhitespace(c) { |
| 2126 | continue |
no test coverage detected