in modules/serialize/src/decode_encryption_context.ts [26:73]
function decodeEncryptionContext(
encodedEncryptionContext: Uint8Array
): Readonly<EncryptionContext> {
const encryptionContext: EncryptionContext = Object.create(null)
/* Check for early return (Postcondition): The case of 0 length is defined as an empty object. */
if (!encodedEncryptionContext.byteLength) {
return Object.freeze(encryptionContext)
}
/* Uint8Array is a view on top of the underlying ArrayBuffer.
* This means that raw underlying memory stored in the ArrayBuffer
* may be larger than the Uint8Array. This is especially true of
* the Node.js Buffer object. The offset and length *must* be
* passed to the DataView otherwise I will get unexpected results.
*/
const dataView = new DataView(
encodedEncryptionContext.buffer,
encodedEncryptionContext.byteOffset,
encodedEncryptionContext.byteLength
)
const pairsCount = dataView.getUint16(0, false) // big endian
const elementInfo = readElements(pairsCount, 2, encodedEncryptionContext, 2)
/* Postcondition: Since the encryption context has a length, it must have pairs.
* Unlike the encrypted data key section, the encryption context has a length
* element. This means I should always pass the entire section.
*/
if (!elementInfo) throw new Error('context parse error')
const { elements, readPos } = elementInfo
/* Postcondition: The byte length of the encodedEncryptionContext must match the readPos. */
needs(
encodedEncryptionContext.byteLength === readPos,
'Overflow, too much data.'
)
for (let count = 0; count < pairsCount; count++) {
const [key, value] = elements[count].map(toUtf8)
/* Postcondition: The number of keys in the encryptionContext must match the pairsCount.
* If the same Key value is serialized...
*/
needs(
encryptionContext[key] === undefined,
'Duplicate encryption context key value.'
)
encryptionContext[key] = value
}
Object.freeze(encryptionContext)
return encryptionContext
}