in src/main/java/com/amazonaws/encryptionsdk/internal/EncryptionContextSerializer.java [136:202]
public static Map<String, String> deserialize(final byte[] b) {
try {
if (b == null) {
return null;
}
if (b.length == 0) {
return (Collections.<String, String>emptyMap());
}
final ByteBuffer encryptionContextBytes = ByteBuffer.wrap(b);
// retrieve the number of entries first
final int entryCount = encryptionContextBytes.getShort();
if (entryCount <= 0 || entryCount > Short.MAX_VALUE) {
throw new AwsCryptoException(
"The number of entries in encryption context must be greater than 0 and smaller than "
+ Short.MAX_VALUE);
}
final CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
// ensure all failures in decoder are reported.
decoder.onMalformedInput(CodingErrorAction.REPORT);
decoder.onUnmappableCharacter(CodingErrorAction.REPORT);
final Map<String, String> result = new HashMap<>(entryCount);
for (int i = 0; i < entryCount; i++) {
// retrieve key
final int keyLen = encryptionContextBytes.getShort();
if (keyLen <= 0 || keyLen > Short.MAX_VALUE) {
throw new AwsCryptoException(
"Key length must be greater than 0 and smaller than " + Short.MAX_VALUE);
}
final ByteBuffer keyBytes = encryptionContextBytes.slice();
Utils.limit(keyBytes, keyLen);
Utils.position(encryptionContextBytes, encryptionContextBytes.position() + keyLen);
final int valueLen = encryptionContextBytes.getShort();
if (valueLen <= 0 || valueLen > Short.MAX_VALUE) {
throw new AwsCryptoException(
"Value length must be greater than 0 and smaller than " + Short.MAX_VALUE);
}
// retrieve value
final ByteBuffer valueBytes = encryptionContextBytes.slice();
Utils.limit(valueBytes, valueLen);
Utils.position(encryptionContextBytes, encryptionContextBytes.position() + valueLen);
final CharBuffer keyChars = decoder.decode(keyBytes);
final CharBuffer valueChars = decoder.decode(valueBytes);
// check for duplicate entries.
if (result.put(keyChars.toString(), valueChars.toString()) != null) {
throw new AwsCryptoException("Encryption context contains duplicate entries.");
}
}
return result;
} catch (CharacterCodingException e) {
throw new IllegalArgumentException(
"Encryption context contains an invalid unicode character");
} catch (BufferUnderflowException e) {
throw new AwsCryptoException("Invalid encryption context. Expected more bytes.", e);
}
}