Fix: Combination of status filters on invoices page causes 500 fatal server error (Fix #6437)

This commit is contained in:
nicolas.dorier
2024-12-04 21:56:45 +09:00
parent 70f97382a4
commit fb8ca19327
3 changed files with 26 additions and 5 deletions

View File

@@ -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")}");

View File

@@ -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

View File

@@ -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);
}