mirror of
https://github.com/actions/runner.git
synced 2025-12-11 12:57:05 +00:00
Stop-Commands: stopToken restrictions (#1371)
* Prevent stopTokens that are workflow commands Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com> * Check context for env var too * Accept true, 1 and $true instead of just "true" * Setup ExpressionValues in tests * Update src/Runner.Common/Constants.cs Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com> * Separate success and fail tests for invalid token * Fix envcontext for tests Co-authored-by: Thomas Boop <52323235+thboop@users.noreply.github.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
||||
using GitHub.DistributedTask.WebApi;
|
||||
using GitHub.Runner.Worker;
|
||||
using GitHub.Runner.Worker.Container;
|
||||
@@ -83,6 +84,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_ec.Setup(x => x.ExpressionValues).Returns(GetExpressionValues());
|
||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Returns((string tag, string line) =>
|
||||
{
|
||||
@@ -105,6 +107,88 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("stop-commands", "1")]
|
||||
[InlineData("", "1")]
|
||||
[InlineData("set-env", "1")]
|
||||
[InlineData("stop-commands", "true")]
|
||||
[InlineData("", "true")]
|
||||
[InlineData("set-env", "true")]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void StopProcessCommand__AllowsInvalidStopTokens__IfEnvVarIsSet(string invalidToken, string allowUnsupportedStopCommandTokens)
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_ec.Object.Global.EnvironmentVariables = new Dictionary<string, string>();
|
||||
var expressionValues = new DictionaryContextData
|
||||
{
|
||||
["env"] =
|
||||
#if OS_WINDOWS
|
||||
new DictionaryContextData{ { Constants.Variables.Actions.AllowUnsupportedStopCommandTokens, new StringContextData(allowUnsupportedStopCommandTokens) }}
|
||||
#else
|
||||
new CaseSensitiveDictionaryContextData{ { Constants.Variables.Actions.AllowUnsupportedStopCommandTokens, new StringContextData(allowUnsupportedStopCommandTokens) }}
|
||||
#endif
|
||||
};
|
||||
_ec.Setup(x => x.ExpressionValues).Returns(expressionValues);
|
||||
_ec.Setup(x => x.JobTelemetry).Returns(new List<JobTelemetry>());
|
||||
|
||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, $"::stop-commands::{invalidToken}", null));
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("stop-commands")]
|
||||
[InlineData("")]
|
||||
[InlineData("set-env")]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void StopProcessCommand__FailOnInvalidStopTokens(string invalidToken)
|
||||
{
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_ec.Object.Global.EnvironmentVariables = new Dictionary<string, string>();
|
||||
_ec.Setup(x => x.ExpressionValues).Returns(GetExpressionValues());
|
||||
_ec.Setup(x => x.JobTelemetry).Returns(new List<JobTelemetry>());
|
||||
Assert.Throws<Exception>(() => _commandManager.TryProcessCommand(_ec.Object, $"::stop-commands::{invalidToken}", null));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void StopProcessCommandAcceptsValidToken()
|
||||
{
|
||||
var validToken = "randomToken";
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_ec.Setup(x => x.ExpressionValues).Returns(GetExpressionValues());
|
||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, $"::stop-commands::{validToken}", null));
|
||||
Assert.False(_commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar", null));
|
||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, $"::{validToken}::", null));
|
||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar", null));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
public void StopProcessCommandMasksValidTokenForEntireRun()
|
||||
{
|
||||
var validToken = "randomToken";
|
||||
using (TestHostContext hc = CreateTestContext())
|
||||
{
|
||||
_ec.Setup(x => x.ExpressionValues).Returns(GetExpressionValues());
|
||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, $"::stop-commands::{validToken}", null));
|
||||
Assert.False(_commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar", null));
|
||||
Assert.Equal("***", hc.SecretMasker.MaskSecrets(validToken));
|
||||
|
||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, $"::{validToken}::", null));
|
||||
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar", null));
|
||||
Assert.Equal("***", hc.SecretMasker.MaskSecrets(validToken));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Trait("Level", "L0")]
|
||||
[Trait("Category", "Worker")]
|
||||
@@ -202,15 +286,15 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
return 1;
|
||||
});
|
||||
|
||||
var registeredCommands = new HashSet<string>(new string[1]{ "warning" });
|
||||
var registeredCommands = new HashSet<string>(new string[1] { "warning" });
|
||||
ActionCommand command;
|
||||
|
||||
|
||||
// Columns when lines are different
|
||||
ActionCommand.TryParseV2("::warning line=1,endLine=2,col=1,endColumn=2::this is a warning", registeredCommands, out command);
|
||||
Assert.Equal("1", command.Properties["col"]);
|
||||
IssueCommandExtension.ValidateLinesAndColumns(command, _ec.Object);
|
||||
Assert.False(command.Properties.ContainsKey("col"));
|
||||
|
||||
|
||||
// No lines with columns
|
||||
ActionCommand.TryParseV2("::warning col=1,endColumn=2::this is a warning", registeredCommands, out command);
|
||||
Assert.Equal("1", command.Properties["col"]);
|
||||
@@ -375,5 +459,19 @@ namespace GitHub.Runner.Common.Tests.Worker
|
||||
|
||||
return hostContext;
|
||||
}
|
||||
|
||||
private DictionaryContextData GetExpressionValues()
|
||||
{
|
||||
return new DictionaryContextData
|
||||
{
|
||||
["env"] =
|
||||
#if OS_WINDOWS
|
||||
new DictionaryContextData()
|
||||
#else
|
||||
new CaseSensitiveDictionaryContextData()
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user