Repository: nifi
Updated Branches:
  refs/heads/master c6af6be44 -> 93795bc7b


NIFI-1915 Fixed '$' escape logic.
Fixed '$' escape logic (if not followed by number) to use 
Matcher.quoteReplacement(java.lang.String) to
suppress its special meaning so it could be treated as literal.

This closes #466.

Signed-off-by: Pierre Villard <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/93795bc7
Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/93795bc7
Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/93795bc7

Branch: refs/heads/master
Commit: 93795bc7ba411077649351b935cb15970a7c417f
Parents: c6af6be
Author: Oleg Zhurakousky <[email protected]>
Authored: Tue May 24 09:30:51 2016 -0400
Committer: Pierre Villard <[email protected]>
Committed: Wed Jun 1 20:17:59 2016 +0200

----------------------------------------------------------------------
 .../nifi/processors/standard/ReplaceText.java   | 21 +++++++++++---
 .../processors/standard/TestReplaceText.java    | 30 ++++++++++++++++++++
 2 files changed, 47 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi/blob/93795bc7/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ReplaceText.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ReplaceText.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ReplaceText.java
index 43a01c7..59e0da6 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ReplaceText.java
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/ReplaceText.java
@@ -73,6 +73,8 @@ import org.apache.nifi.util.StopWatch;
     + "the content that matches the Regular Expression with some alternate 
value.")
 public class ReplaceText extends AbstractProcessor {
 
+    private static Pattern REPLACEMENT_NORMALIZATION_PATTERN = 
Pattern.compile("(\\$\\D)");
+
     // Constants
     public static final String LINE_BY_LINE = "Line-by-Line";
     public static final String ENTIRE_TEXT = "Entire text";
@@ -520,8 +522,7 @@ public class ReplaceText extends AbstractProcessor {
                     String replacement = 
context.getProperty(REPLACEMENT_VALUE).evaluateAttributeExpressions(flowFile, 
additionalAttrs, escapeBackRefDecorator).getValue();
                     replacement = escapeLiteralBackReferences(replacement, 
numCapturingGroups);
 
-                    // If we have a $ followed by anything other than a 
number, then escape it. E.g., $d becomes \$d so that it can be used as a 
literal in a regex.
-                    final String replacementFinal = 
replacement.replaceAll("(\\$\\D)", "\\\\$1");
+                    String replacementFinal = 
normalizeReplacementString(replacement);
 
                     final String updatedValue = 
contentString.replaceAll(searchRegex, replacementFinal);
                     updatedFlowFile = session.write(flowFile, new 
OutputStreamCallback() {
@@ -553,8 +554,7 @@ public class ReplaceText extends AbstractProcessor {
                                     String replacement = 
context.getProperty(REPLACEMENT_VALUE).evaluateAttributeExpressions(flowFile, 
additionalAttrs, escapeBackRefDecorator).getValue();
                                     replacement = 
escapeLiteralBackReferences(replacement, numCapturingGroups);
 
-                                    // If we have a $ followed by anything 
other than a number, then escape it. E.g., $d becomes \$d so that it can be 
used as a literal in a regex.
-                                    final String replacementFinal = 
replacement.replaceAll("(\\$\\D)", "\\\\$1");
+                                    String replacementFinal = 
normalizeReplacementString(replacement);
 
                                     final String updatedValue = 
oneLine.replaceAll(searchRegex, replacementFinal);
                                     bw.write(updatedValue);
@@ -635,6 +635,19 @@ public class ReplaceText extends AbstractProcessor {
         }
     }
 
+    /**
+     * If we have a '$' followed by anything other than a number, then escape
+     * it. E.g., '$d' becomes '\$d' so that it can be used as a literal in a
+     * regex.
+     */
+    private static String normalizeReplacementString(String replacement) {
+        String replacementFinal = replacement;
+        if (REPLACEMENT_NORMALIZATION_PATTERN.matcher(replacement).find()) {
+            replacementFinal = Matcher.quoteReplacement(replacement);
+        }
+        return replacementFinal;
+    }
+
     private interface ReplacementStrategyExecutor {
         FlowFile replace(FlowFile flowFile, ProcessSession session, 
ProcessContext context, String evaluateMode, Charset charset, int 
maxBufferSize);
 

http://git-wip-us.apache.org/repos/asf/nifi/blob/93795bc7/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestReplaceText.java
----------------------------------------------------------------------
diff --git 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestReplaceText.java
 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestReplaceText.java
index 561a1e0..a6e0971 100644
--- 
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestReplaceText.java
+++ 
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestReplaceText.java
@@ -64,6 +64,36 @@ public class TestReplaceText {
     }
 
     @Test
+    public void testWithEscaped$InReplacemenmt() throws IOException {
+        final TestRunner runner = TestRunners.newTestRunner(new ReplaceText());
+        runner.setValidateExpressionUsage(false);
+        runner.setProperty(ReplaceText.SEARCH_VALUE, "(?s:^.*$)");
+        runner.setProperty(ReplaceText.REPLACEMENT_VALUE, "a\\$b");
+
+        runner.enqueue("a$a,b,c,d");
+        runner.run();
+
+        runner.assertAllFlowFilesTransferred(ReplaceText.REL_SUCCESS, 1);
+        final MockFlowFile out = 
runner.getFlowFilesForRelationship(ReplaceText.REL_SUCCESS).get(0);
+        out.assertContentEquals("a\\$b".getBytes("UTF-8"));
+    }
+
+    @Test
+    public void testWithUnEscaped$InReplacemenmt() throws IOException {
+        final TestRunner runner = TestRunners.newTestRunner(new ReplaceText());
+        runner.setValidateExpressionUsage(false);
+        runner.setProperty(ReplaceText.SEARCH_VALUE, "(?s:^.*$)");
+        runner.setProperty(ReplaceText.REPLACEMENT_VALUE, "a$b");
+
+        runner.enqueue("a$a,b,c,d");
+        runner.run();
+
+        runner.assertAllFlowFilesTransferred(ReplaceText.REL_SUCCESS, 1);
+        final MockFlowFile out = 
runner.getFlowFilesForRelationship(ReplaceText.REL_SUCCESS).get(0);
+        out.assertContentEquals("a$b".getBytes("UTF-8"));
+    }
+
+    @Test
     public void testPrependSimple() throws IOException {
         final TestRunner runner = TestRunners.newTestRunner(new ReplaceText());
         runner.setValidateExpressionUsage(false);

Reply via email to