Fix: Combination of status filters on invoices page causes 500 fatal server error (Fix #6437)
This commit is contained in:
@@ -838,6 +838,8 @@ namespace BTCPayServer.Tests
|
||||
AssertSearchInvoice(acc, false, invoice.Id, "exceptionstatus:paidOver");
|
||||
AssertSearchInvoice(acc, true, invoice.Id, "unusual:true");
|
||||
AssertSearchInvoice(acc, false, invoice.Id, "unusual:false");
|
||||
AssertSearchInvoice(acc, true, invoice.Id, "status:settled,exceptionstatus:paidPartial");
|
||||
AssertSearchInvoice(acc, true, invoice.Id, "status:settled,status:invalid,exceptionstatus:paidPartial,exceptionstatus:paidOver");
|
||||
|
||||
var time = invoice.InvoiceTime;
|
||||
AssertSearchInvoice(acc, true, invoice.Id, $"startdate:{time.ToString("yyyy-MM-dd HH:mm:ss")}");
|
||||
|
@@ -6,6 +6,7 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.WebSockets;
|
||||
using System.Reflection;
|
||||
@@ -625,6 +626,23 @@ namespace BTCPayServer
|
||||
return supportedChains.Contains(cryptoCode.ToUpperInvariant());
|
||||
}
|
||||
|
||||
class ParameterReplacer : ExpressionVisitor
|
||||
{
|
||||
private Dictionary<string, ParameterExpression> _Parameters;
|
||||
|
||||
protected override Expression VisitLambda<T>(Expression<T> node)
|
||||
{
|
||||
_Parameters = node.Parameters.ToDictionary(p => p.Name);
|
||||
return base.VisitLambda(node);
|
||||
}
|
||||
protected override Expression VisitParameter(ParameterExpression node)
|
||||
{
|
||||
return _Parameters[node.Name];
|
||||
}
|
||||
}
|
||||
public static TExpr ReplaceParameterRef<TExpr>(this TExpr expression) where TExpr : Expression
|
||||
=> (TExpr)new ParameterReplacer().Visit(expression);
|
||||
|
||||
public static IActionResult RedirectToRecoverySeedBackup(this Controller controller, RecoverySeedBackupViewModel vm)
|
||||
{
|
||||
var redirectVm = new PostRedirectViewModel
|
||||
|
@@ -710,14 +710,15 @@ retry:
|
||||
{
|
||||
exceptionStatusExpression = i => exceptionStatusSet.Contains(i.ExceptionStatus);
|
||||
}
|
||||
(Expression predicate, ParameterExpression parameter) = (statusExpression, exceptionStatusExpression) switch
|
||||
var predicate = (statusExpression, exceptionStatusExpression) switch
|
||||
{
|
||||
({ } a, { } b) => ((Expression)Expression.Or(a.Body, b.Body), a.Parameters[0]),
|
||||
({ } a, null) => (a.Body, a.Parameters[0]),
|
||||
(null, { } b) => (b.Body, b.Parameters[0]),
|
||||
({ } a, { } b) => (Expression)Expression.Or(a.Body, b.Body),
|
||||
({ } a, null) => a.Body,
|
||||
(null, { } b) => b.Body,
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
var expression = Expression.Lambda<Func<InvoiceData, bool>>(predicate, parameter);
|
||||
var expression = Expression.Lambda<Func<InvoiceData, bool>>(predicate, Expression.Parameter(typeof(InvoiceData), "i"));
|
||||
expression = expression.ReplaceParameterRef();
|
||||
query = query.Where(expression);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user