diff --git a/modules/nextflow/src/main/groovy/nextflow/processor/TaskConfig.groovy b/modules/nextflow/src/main/groovy/nextflow/processor/TaskConfig.groovy index cb78900b33..71cb92afb8 100644 --- a/modules/nextflow/src/main/groovy/nextflow/processor/TaskConfig.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/processor/TaskConfig.groovy @@ -380,14 +380,26 @@ class TaskConfig extends LazyMap implements Cloneable { return BashWrapperBuilder.BASH if( value instanceof List ) - return (List)value + return validateShell(value as List) if( value instanceof CharSequence ) - return [ value.toString() ] + return validateShell(List.of(value.toString())) throw new IllegalArgumentException("Not a valid `shell` configuration value: ${value}") } + protected List validateShell(List shell) { + for( String it : shell ) { + if( !it ) + throw new IllegalArgumentException("Directive `process.shell` cannot contain empty values - offending value: ${shell}") + if( !it || it.contains('\n') || it.contains('\r') ) + throw new IllegalArgumentException("Directive `process.shell` cannot contain new-line characters - offending value: ${shell}") + if( it.startsWith(' ') || it.endsWith(' ')) + throw new IllegalArgumentException("Directive `process.shell` cannot contain leading or tralining blanks - offending value: ${shell}") + } + return shell + } + Path getStoreDir() { def path = get('storeDir') if( !path ) diff --git a/modules/nextflow/src/test/groovy/nextflow/processor/TaskConfigTest.groovy b/modules/nextflow/src/test/groovy/nextflow/processor/TaskConfigTest.groovy index e2a09b1fdf..b997c00a25 100644 --- a/modules/nextflow/src/test/groovy/nextflow/processor/TaskConfigTest.groovy +++ b/modules/nextflow/src/test/groovy/nextflow/processor/TaskConfigTest.groovy @@ -671,4 +671,28 @@ class TaskConfigTest extends Specification { def e = thrown(ProcessUnrecoverableException) e.message == "Directive 'resourceLimits.cpus' cannot be a negative value - offending value: -1" } + + def 'should validate shell cli' () { + given: + def config = new TaskConfig([:]) + when: + config.validateShell(['bash','this','that']) + then: + noExceptionThrown() + + when: + config.validateShell(['']) + then: + thrown(IllegalArgumentException) + + when: + config.validateShell(['bash\nthis\nthat']) + then: + thrown(IllegalArgumentException) + + when: + config.validateShell(['bash', ' -eu ']) + then: + thrown(IllegalArgumentException) + } }