From 1edd5ee5ee85ac205fcb4c46a748f07a01e5c0ad Mon Sep 17 00:00:00 2001 From: Joe Hull Date: Fri, 21 Jan 2022 09:07:24 -0800 Subject: [PATCH] Avoid ArgumentOutOfRangeException in ExpressionHelper.CheckForString (#1649) --- src/Generator/Passes/ExpressionHelper.cs | 13 +++++++++++-- tests/CSharp/CSharp.Tests.cs | 9 +++++++++ tests/CSharp/CSharp.h | 12 ++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/Generator/Passes/ExpressionHelper.cs b/src/Generator/Passes/ExpressionHelper.cs index ca9c011a..90f71be9 100644 --- a/src/Generator/Passes/ExpressionHelper.cs +++ b/src/Generator/Passes/ExpressionHelper.cs @@ -427,8 +427,17 @@ namespace CppSharp.Internal if (typeInSignature is CILType managed && managed.Type == typeof(string)) { - result = result[result.IndexOf("\"")..]; - return true; + // It is possible that "result" is not a string literal. See, for + // example, the test case MoreVariablesWithInitializer in CSharp.h. + // Test for presence of a quote first to avoid + // ArgumentOutOfRangeException. + var initialQuoteIndex = result.IndexOf("\""); + if (initialQuoteIndex >= 0) + { + result = result[initialQuoteIndex..]; + return true; + } + return false; } } return false; diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/CSharp/CSharp.Tests.cs index 33fecdd5..aedb1479 100644 --- a/tests/CSharp/CSharp.Tests.cs +++ b/tests/CSharp/CSharp.Tests.cs @@ -934,6 +934,15 @@ public unsafe class CSharpTests Assert.That(VariablesWithInitializer.BoolArray, Is.EqualTo(new[] { false, true })); } + [Test] + public void TestIndirectVariableInitializer() + { + // The actual test is that the generator doesn't throw when generating + // IndependentStringVariable. If we're running the test, we must have + // generated CSharp.cs without crashing the generator. + Assert.That(MoreVariablesWithInitializer.DependentStringVariable, Is.EqualTo(MoreVariablesWithInitializer.IndependentStringVariable)); + } + [Test] public void TestPointerPassedAsItsSecondaryBase() { diff --git a/tests/CSharp/CSharp.h b/tests/CSharp/CSharp.h index 3a222386..faffaf76 100644 --- a/tests/CSharp/CSharp.h +++ b/tests/CSharp/CSharp.h @@ -1096,6 +1096,18 @@ public: static constexpr float FloatArray[2] { 0.5020f, 0.6020f }; }; +// Try to precipitate an ArgumentOutOfRangeException in ExpressionHelper.CheckForString. +// +// Note that uncommenting DLL_API below results in different behavior in +// ExpressionHelper.PrintExpression. In particular, ExpressionHelper.CheckForString is not +// called and no ArgumentOutOfRangeException is generated. +#define STRING_INITIALIZER "The quick brown fox" +struct /*DLL_API*/ MoreVariablesWithInitializer +{ + static constexpr const char* IndependentStringVariable = STRING_INITIALIZER; + static constexpr const char* DependentStringVariable = IndependentStringVariable; +}; + typedef void (*ALLCAPS_UNDERSCORES)(int i); class DLL_API TestString