Skip to content

Commit

Permalink
[FIXED JENKINS-38818] Correctly escape string constants when generati…
Browse files Browse the repository at this point in the history
…ng groovy from AST
  • Loading branch information
stephenc committed Oct 7, 2016
1 parent 366510a commit 506647b
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 7 deletions.
Expand Up @@ -94,14 +94,24 @@ public final class ModelASTPipelineDef extends ModelASTElement {
List<String> rawLines = toGroovy().split("\n")

int indentCount = 0
boolean tripleSingleQuotedString = false;

rawLines.each { r ->
if (r.startsWith("}") || r.startsWith(")") || r.startsWith("]")) {
indentCount -= 1
if (tripleSingleQuotedString) {
prettyLines << r
} else {
if (r.startsWith("}") || r.startsWith(")") || r.startsWith("]")) {
indentCount -= 1
}
prettyLines << "${indent(indentCount)}${r}"
if (r.endsWith("{") || r.endsWith("(") || r.endsWith("[")) {
indentCount += 1
}
}
prettyLines << "${indent(indentCount)}${r}"
if (r.endsWith("{") || r.endsWith("(") || r.endsWith("[")) {
indentCount += 1
int index = r.indexOf("\'\'\'");
while (index != -1) {
tripleSingleQuotedString = !tripleSingleQuotedString;
index = r.indexOf("\'\'\'", index + 3);
}
}

Expand Down
Expand Up @@ -83,7 +83,11 @@ public abstract class ModelASTValue extends ModelASTElement {
@Override
public String toGroovy() {
if (o instanceof String) {
return "'${o}'"
if (o.indexOf('\n') == -1) {
return "'${o.replace("'", "\\'")}'"
} else {
return "\'\'\'${o.replace('\'\'\'',"\\\'\\\\'\\\\'")}\'\'\'"
}
} else {
return o
}
Expand Down
Expand Up @@ -101,7 +101,8 @@ public void setUp() throws Exception {
"simplePostBuild",
"simpleTools",
"legacyMetaStepSyntax",
"globalLibrarySuccess"
"globalLibrarySuccess",
"stringsNeedingEscapeLogic"
);

public static Iterable<Object[]> configsWithErrors() {
Expand Down
34 changes: 34 additions & 0 deletions src/test/resources/json/stringsNeedingEscapeLogic.json
@@ -0,0 +1,34 @@
{
"pipeline": {
"stages": [
{
"name": "foo",
"branches": [
{
"name": "default",
"steps": [
{
"name": "echo",
"arguments": {
"isLiteral": true,
"value": "Hello!\n'How are you?', said script A\n\n\"I am fine '''really'''\" said script B\n\n"
}
},
{
"name": "echo",
"arguments": {
"isLiteral": true,
"value": "echo \"\n'quoted'\""
}
}
]
}
]
}
],
"agent": {
"isLiteral": true,
"value": "none"
}
}
}
41 changes: 41 additions & 0 deletions src/test/resources/stringsNeedingEscapeLogic.groovy
@@ -0,0 +1,41 @@
/*
* The MIT License
*
* Copyright (c) 2016, CloudBees, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

pipeline {
agent none
stages {
stage("foo") {
echo '''Hello!
'How are you?', said script A
"I am fine \'\'\'really\'\'\'" said script B
'''
echo 'echo "\'quoted\'"'
}
}
}



0 comments on commit 506647b

Please sign in to comment.