SYS-REQ-112
(data []byte, offset int, open byte)
| 2199 | |
| 2200 | // SYS-REQ-112 |
| 2201 | func scanContainerLen(data []byte, offset int, open byte) (int, error) { |
| 2202 | const ( |
| 2203 | scanArrayValue = iota |
| 2204 | scanArrayPrimitive |
| 2205 | scanArrayDelimiter |
| 2206 | scanObjectKey |
| 2207 | scanObjectColon |
| 2208 | scanObjectValue |
| 2209 | scanObjectPrimitive |
| 2210 | scanObjectDelimiter |
| 2211 | ) |
| 2212 | |
| 2213 | close := byte(']') |
| 2214 | malformedErr := MalformedArrayError |
| 2215 | state := scanArrayValue |
| 2216 | if open == '{' { |
| 2217 | close = '}' |
| 2218 | malformedErr = MalformedObjectError |
| 2219 | state = scanObjectKey |
| 2220 | } |
| 2221 | |
| 2222 | var fixedStack [32]byte |
| 2223 | stack := fixedStack[:1] |
| 2224 | stack[0] = close |
| 2225 | |
| 2226 | count := 0 |
| 2227 | primitiveStart := -1 |
| 2228 | |
| 2229 | for i := offset + 1; i < len(data); i++ { |
| 2230 | c := data[i] |
| 2231 | |
| 2232 | // Only delimiters at the addressed container's top level affect its |
| 2233 | // length. Strings and nested containers are skipped structurally. |
| 2234 | if len(stack) > 1 { |
| 2235 | switch c { |
| 2236 | case '"': |
| 2237 | stringLength, _ := stringEnd(data[i+1:]) |
| 2238 | if stringLength == -1 { |
| 2239 | return 0, malformedErr |
| 2240 | } |
| 2241 | i += stringLength |
| 2242 | case '[': |
| 2243 | stack = append(stack, ']') |
| 2244 | case '{': |
| 2245 | stack = append(stack, '}') |
| 2246 | case ']', '}': |
| 2247 | if c != stack[len(stack)-1] { |
| 2248 | return 0, malformedErr |
| 2249 | } |
| 2250 | stack = stack[:len(stack)-1] |
| 2251 | } |
| 2252 | continue |
| 2253 | } |
| 2254 | |
| 2255 | switch state { |
| 2256 | case scanArrayValue: |
| 2257 | if isContainerWhitespace(c) { |
| 2258 | continue |
no test coverage detected