Вложенное "использование" приводит к сбою.net среды выполнения при использовании с CryptoStream
У нас есть этот простой код, который был преобразован из vb.net, где он не был создан с использованием using/end using
, Во время конвертации мы использовали using
в с #.
using (var memStream = new MemoryStream() { Position = 0L })
using (ICryptoTransform cryptoTransfrom = (new TripleDESCryptoServiceProvider()).CreateDecryptor(_key, _iv))
{
using (var cryptStream = new CryptoStream(memStream, cryptoTransfrom, CryptoStreamMode.Write))
{
// <-- here used to be try
string convertedValue = ConvertHexToDec(value);
byte[] decryptBytes = Convert.FromBase64String(convertedValue); //<-- Error line
// <-- here used to be catch/throw
cryptStream.Write(decryptBytes, 0, decryptBytes.Length);
cryptStream.FlushFinalBlock();
cryptStream.Close();
}
decodedVal = Encoding.ASCII.GetString(memStream.ToArray());
}
Но был try/catch
(см. комментарии) окружающие Convert.FromBase64String(convertedValue)
, То, что мы не поняли, это то, что value
иногда получалось как простое, не закодированное в base64 значение. Таким образом, когда некодированное значение попадет в "Ошибка строки" - try/catch
сделал дело перебросить. Но когда вы смотрите на код выше, когда такое значение вызывает исключение в этой строке - .NET Runtime вылетает. Вот журнал событий
.NET Runtime версия 2.0.50727.5485 - Неустранимая ошибка механизма выполнения (000007FEE581600A) (80131506)
И исключение, конечно, просто нормально
Недопустимый символ в строке Base-64.
Я исправил куплю сняв внутренний using
using (var memStream = new MemoryStream() { Position = 0L })
using (ICryptoTransform cryptoTransfrom = (new TripleDESCryptoServiceProvider()).CreateDecryptor(_key, _iv))
{
var cryptStream = new CryptoStream(memStream, cryptoTransfrom, CryptoStreamMode.Write);
string convertedValue = ConvertHexToDec(value);
byte[] decryptBytes = Convert.FromBase64String(convertedValue); //<-- Error line
cryptStream.Write(decryptBytes, 0, decryptBytes.Length);
cryptStream.FlushFinalBlock();
cryptStream.Close();
decodedVal = Encoding.ASCII.GetString(memStream.ToArray());
}
Теперь ошибка, конечно, все еще возникает, но она не приводит к сбою.NET Runtime, поэтому работает нормально. Также размещение try/catch-rethrow
где это было раньше, предотвратило бы и такой сбой.
Я подозреваю, что это имеет отношение к вложенным using
, внутренний using
на самом деле не нужно, потому что CryptoStream
просто оборачивает поток памяти и преобразование. И если ошибка происходит внутри фигурных скобок, она будет распространена на try/catch
трансформации сначала, а затем поток памяти.
Но может ли кто-нибудь объяснить такое поведение, учитывая, что это происходит только тогда, когда сборка выполняется для x64 и выполняется в пуле ASP.NET x64? Когда приложение скомпилировано для x86 и работает в 32-битном пуле, этого не происходит.
1 ответ
Это, несомненно, ошибка во время выполнения. Поскольку вы используете крайне старую версию среды выполнения, мой совет - обновить.
Но может ли кто-нибудь объяснить такое поведение, учитывая, что это происходит только тогда, когда сборка выполняется для x64 и выполняется в пуле ASP.NET x64? Когда приложение скомпилировано для x86 и работает в 32-битном пуле, этого не происходит.
Дрожания x64 и x86 были совершенно разными кодовыми базами в этой версии. Ошибка, достаточно серьезная, чтобы вызвать сбой среды выполнения, включающий странные ошибки кодагена во вложенных блоках try-finally, почти наверняка будет уникальной для конкретного джиттера.