Skip to content

Commit 43d10bf

Browse files
committed
openssl_error_string()
1 parent 1db0682 commit 43d10bf

File tree

1 file changed

+62
-5
lines changed

1 file changed

+62
-5
lines changed

src/Peachpie.Library/OpenSSL.cs

+62-5
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,64 @@ private enum CipherType { AES, DES, TripleDES };
9494

9595
#endregion
9696

97-
#region openssl_encrypt/decrypt
97+
#region openssl_error_string
98+
99+
sealed class ErrorList
100+
{
101+
/// <summary>
102+
/// Stack of error messages.
103+
/// </summary>
104+
readonly Stack<string> _messages = new Stack<string>();
105+
106+
public void Push(string message)
107+
{
108+
_messages.Push(message ?? throw new ArgumentNullException(nameof(message)));
109+
}
110+
111+
public bool TryPop(out string message)
112+
{
113+
if (_messages.Count != 0)
114+
{
115+
message = _messages.Pop();
116+
return true;
117+
}
118+
else
119+
{
120+
message = null;
121+
return false;
122+
}
123+
}
124+
}
125+
126+
/// <summary>
127+
/// Helper method that stores an openssl error message within the current context.
128+
/// </summary>
129+
private static void HandleError(Context ctx, string message)
130+
{
131+
ctx.GetStatic<ErrorList>().Push(message);
132+
PhpException.Throw(PhpError.E_WARNING, message);
133+
}
134+
135+
/// <summary>
136+
/// Gets the last error from the openSSL functions.
137+
/// Error messages are queued, so this function should be called multiple times to collect all of the information.
138+
/// The last error will be the most recent one.
139+
/// </summary>
140+
[return: CastToFalse]
141+
public static string openssl_error_string(Context ctx)
142+
{
143+
if (ctx.TryGetStatic<ErrorList>(out var list) && list.TryPop(out var message))
144+
{
145+
return message;
146+
}
147+
148+
// FALSE: no more errors
149+
return null;
150+
}
151+
152+
#endregion
153+
154+
#region openssl_encrypt, openssl_decrypt
98155

99156
private static SymmetricAlgorithm PrepareCipher(byte[] decodedKey, Cipher cipher, byte[] iv, Options options)
100157
{
@@ -174,7 +231,7 @@ public static string openssl_decrypt(Context ctx, PhpString data, string method,
174231
if (!Ciphers.TryGetValue(method, out var cipherMethod))
175232
{
176233
// Unknown cipher algorithm.
177-
PhpException.Throw(PhpError.E_WARNING, Resources.LibResources.openssl_unknown_cipher);
234+
HandleError(ctx, Resources.LibResources.openssl_unknown_cipher);
178235
return default; // FALSE
179236
}
180237

@@ -189,7 +246,7 @@ public static string openssl_decrypt(Context ctx, PhpString data, string method,
189246
}
190247
catch (CryptographicException ex)
191248
{
192-
PhpException.Throw(PhpError.E_WARNING, ex.Message);
249+
HandleError(ctx, ex.Message);
193250
return default; // FALSE
194251
}
195252
}
@@ -234,7 +291,7 @@ public static PhpString openssl_encrypt(Context ctx, string data, string method,
234291
if (!Ciphers.TryGetValue(method, out var cipherMethod))
235292
{
236293
// Unknown cipher algorithm.
237-
PhpException.Throw(PhpError.E_WARNING, Resources.LibResources.openssl_unknown_cipher);
294+
HandleError(ctx, Resources.LibResources.openssl_unknown_cipher);
238295
return default; // FALSE
239296
}
240297

@@ -255,7 +312,7 @@ public static PhpString openssl_encrypt(Context ctx, string data, string method,
255312
}
256313
catch (CryptographicException ex)
257314
{
258-
PhpException.Throw(PhpError.E_WARNING, ex.Message);
315+
HandleError(ctx, ex.Message);
259316
return default; // FALSE
260317
}
261318
}

0 commit comments

Comments
 (0)