diff options
author | 2018-01-29 08:23:47 -0800 | |
---|---|---|
committer | 2018-01-29 08:25:35 -0800 | |
commit | 45cb2e86d18a6fbb45d3711fa7bd9f8046a15a08 (patch) | |
tree | cfd5bb16aa42b2021296b79f31d09362e1baa395 | |
parent | a35488e8ee09ca83623422f2dca3f0adc4507155 (diff) |
Do not crash when ctx.action.args.add map_fn returns a list of the wrong length.
PiperOrigin-RevId: 183668291
3 files changed, 39 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java index 4bf9999f50..327c73697c 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkActionFactory.java @@ -950,7 +950,8 @@ public class SkylarkActionFactory implements SkylarkValue { noneable = true, doc = "The passed objects are passed through a map function. " - + "For vector args the function is given a list and is expected to return a list." + + "For vector args the function is given a list and is expected to " + + "return a list of the same length as the input." ) }, useLocation = true diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkCustomCommandLine.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkCustomCommandLine.java index e67ff39f09..c9e5a7ddf9 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkCustomCommandLine.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkCustomCommandLine.java @@ -144,6 +144,16 @@ class SkylarkCustomCommandLine extends CommandLine { null)); } List resultAsList = (List) result; + if (resultAsList.size() != count) { + throw new CommandLineExpansionException( + errorMessage( + String.format( + "map_fn must return a list of the same length as the input. " + + "Found list of length %d, expected %d.", + resultAsList.size(), count), + location, + null)); + } mutatedValues.clear(); mutatedValues.addAll(resultAsList); } diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java index 877bcf8786..6d78fe5e69 100644 --- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java +++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleImplementationFunctionsTest.java @@ -1986,6 +1986,33 @@ public class SkylarkRuleImplementationFunctionsTest extends SkylarkTestCase { } @Test + public void testLazyArgMapFnReturnsWrongArgumentCount() throws Exception { + SkylarkRuleContext ruleContext = createRuleContext("//foo:foo"); + evalRuleContextCode( + ruleContext, + "args = ruleContext.actions.args()", + "def bad_fn(args): return [0]", + "args.add([1, 2], map_fn=bad_fn)", + "ruleContext.actions.run(", + " inputs = depset(ruleContext.files.srcs),", + " outputs = ruleContext.files.srcs,", + " arguments = [args],", + " executable = ruleContext.files.tools[0],", + ")"); + SpawnAction action = + (SpawnAction) + Iterables.getOnlyElement( + ruleContext.getRuleContext().getAnalysisEnvironment().getRegisteredActions()); + try { + action.getArguments(); + fail(); + } catch (CommandLineExpansionException e) { + assertThat(e.getMessage()) + .contains("map_fn must return a list of the same length as the input"); + } + } + + @Test public void createShellWithLazyArgs() throws Exception { SkylarkRuleContext ruleContext = createRuleContext("//foo:foo"); evalRuleContextCode( |