EPPlus icon indicating copy to clipboard operation
EPPlus copied to clipboard

Non-Full-Trust environments throw System.Security.VerificationException on simple formula calculation

Open jochenwezel opened this issue 4 years ago • 4 comments

Problem description

  • Given is a cell with a formula "500*4" and a call to calculate this cell
  • On some framework versions and different trust-environments, the .NET runtime throws a System.Security.VerificationException : Operation could destabilize the runtime on entering method public override CompileResult Compile()
    • System.Security.VerificationException is catched internally and the resulting cell error value will be #VALUE! (instead of 2000)
  • In fact, the compiler shows an 'information' item Use coalesce expression (IDE0030) pointing to that same method.
  • Bug is related to all EPPlus 4.5 as well as EPPlus 5.x

EPPlus\FormulaParsing\ExpressionGraph\IntegerExpression.cs

Code before patch

        public override CompileResult Compile()
        {
            double result = _compiledValue.HasValue ? _compiledValue.Value : double.Parse(ExpressionString, CultureInfo.InvariantCulture);
            result = _negate ? result*-1 : result;
            return new CompileResult(result, DataType.Integer);
        }

Code after patch

        public override CompileResult Compile()
        {
            double result = _compiledValue ?? double.Parse(ExpressionString, CultureInfo.InvariantCulture);
            result = _negate ? result*-1 : result;
            return new CompileResult(result, DataType.Integer);
        }

EPPlus\FormulaParsing\ExpressionGraph\DecimalExpression.cs

Code before patch

        public override CompileResult Compile()
        {
            double result = _compiledValue.HasValue ? _compiledValue.Value : double.Parse(ExpressionString, CultureInfo.InvariantCulture);
            result = _negate ? result * -1 : result;
            return new CompileResult(result, DataType.Decimal);
        }

Code after patch

        public override CompileResult Compile()
        {
            double result =  _compiledValue ?? double.Parse(ExpressionString, CultureInfo.InvariantCulture);
            result = _negate ? result * -1 : result;
            return new CompileResult(result, DataType.Decimal);
        }

jochenwezel avatar Feb 17 '21 14:02 jochenwezel

Thank you, I’ll have a look at this.

swmal avatar Feb 18 '21 16:02 swmal

I have changed this in the two Expressions and it will be included in v 5.6. We will have to go through the entire codebase, because we have more of these... Will happen, but not sure if it will be done until 5.6.

swmal avatar Mar 04 '21 13:03 swmal

To identify the code base that needs to be modify, you can use PEVerify.exe. You will get the "Cannot change initonly field outside its .ctor" error when code base needs to be fixed. For some reason this does not affect .NET core.

PEVerify.exe EPPlus.dll

Microsoft (R) .NET Framework PE Verifier.  Version  4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

[IL]: Error: [C:\Users\username\source\repos\ConsoleApp1\ConsoleApp1\bin\Debug\EPPlus.dll : OfficeOpenXml.Packaging.Ionic.Zip.SharedUtilities::_HRForException][offset 0x00000001] Method is not visible.
[IL]: Error: [C:\Users\djx2842\source\repos\ConsoleApp1\ConsoleApp1\bin\Debug\EPPlus.dll : OfficeOpenXml.FormulaParsing.ExpressionGraph.DecimalExpression::Compile][offset 0x00000001] Cannot change initonly field outside its .ctor.
[IL]: Error: [C:\Users\username\source\repos\ConsoleApp1\ConsoleApp1\bin\Debug\EPPlus.dll : OfficeOpenXml.FormulaParsing.ExpressionGraph.IntegerExpression::Compile][offset 0x00000001] Cannot change initonly field outside its .ctor.
[IL]: Error: [C:\Users\username\source\repos\ConsoleApp1\ConsoleApp1\bin\Debug\EPPlus.dll : OfficeOpenXml.FormulaParsing.Excel.Operators.Operator::ToString][offset 0x00000006] Cannot change initonly field outside its .ctor.
4 Error(s) Verifying EPPlus.dll

maxverro avatar Aug 03 '22 12:08 maxverro

It would be great to see this issue fixed, as it's the main blocker reason for us before further testing can continue for upgrading from v4.5 to an up-to-date release :-)

jochenwezel avatar Aug 03 '22 14:08 jochenwezel

Hi, Apologies for the late reply to your last messages. @maxverro - Row 2 and 3 (DecimalExpression and IntegerExpression) were fixed in 5.8.8, are you using an older version?

The other two (_HRForException and Operator::ToString()) have now been removed from the codebase in our develop branch (see the commit below) and PEVerify now validates EPPlus.dll without errors.

image

I will fix this in our branch for EPPlus 5 too, so it will be included in our next revision (6.0.8/5.8.14).

swmal avatar Sep 01 '22 09:09 swmal

The failed build indicator on the last commit can be ignored. Here is a link to the latest build for EPPlus 5: https://ci.appveyor.com/project/EPPlusSoftware/epplus5

This will be released in the next version for EPPlus 5 and 6.

swmal avatar Sep 05 '22 08:09 swmal

The adjustments we have made to get rid of these warnings are included in 5.8.14 and 6.0.8 (released on Nuget today).

swmal avatar Sep 21 '22 12:09 swmal