private CBORObject ReadStringArrayMap(int type, long uadditional) { bool canonical = this.options.Ctap2Canonical; if (type == 2 || type == 3) // Byte string or text string { if ((uadditional >> 31) != 0) { throw new CBORException("Length of " + ToUnsignedEInteger(uadditional).ToString() + " is bigger" + "\u0020than supported"); } int hint = (uadditional > Int32.MaxValue || (uadditional >> 63) != 0) ? Int32.MaxValue : (int)uadditional; byte[] data = ReadByteData(this.stream, uadditional, null); if (type == 3) { if (!CBORUtilities.CheckUtf8(data)) { throw new CBORException("Invalid UTF-8"); } return(this.ObjectFromUtf8Array(data, hint)); } else { return(this.ObjectFromByteArray(data, hint)); } } if (type == 4) // Array { if (this.options.Ctap2Canonical && this.depth >= 4) { throw new CBORException("Depth too high in canonical CBOR"); } CBORObject cbor = CBORObject.NewArray(); if ((uadditional >> 31) != 0) { throw new CBORException("Length of " + ToUnsignedEInteger(uadditional).ToString() + " is bigger than" + "\u0020supported"); } if (PropertyMap.ExceedsKnownLength(this.stream, uadditional)) { throw new CBORException("Remaining data too small for array" + "\u0020length"); } ++this.depth; for (long i = 0; i < uadditional; ++i) { cbor.Add( this.ReadInternal()); } --this.depth; return(cbor); } if (type == 5) // Map, type 5 { if (this.options.Ctap2Canonical && this.depth >= 4) { throw new CBORException("Depth too high in canonical CBOR"); } CBORObject cbor = CBORObject.NewMap(); if ((uadditional >> 31) != 0) { throw new CBORException("Length of " + ToUnsignedEInteger(uadditional).ToString() + " is bigger than" + "\u0020supported"); } if (PropertyMap.ExceedsKnownLength(this.stream, uadditional)) { throw new CBORException("Remaining data too small for map" + "\u0020length"); } CBORObject lastKey = null; IComparer <CBORObject> comparer = CBORCanonical.Comparer; for (long i = 0; i < uadditional; ++i) { ++this.depth; CBORObject key = this.ReadInternal(); CBORObject value = this.ReadInternal(); --this.depth; if (this.options.Ctap2Canonical && lastKey != null) { int cmp = comparer.Compare(lastKey, key); if (cmp > 0) { throw new CBORException("Map key not in canonical order"); } else if (cmp == 0) { throw new CBORException("Duplicate map key"); } } if (!this.options.AllowDuplicateKeys) { if (cbor.ContainsKey(key)) { throw new CBORException("Duplicate key already exists"); } } lastKey = key; cbor[key] = value; } return(cbor); } return(null); }