From 29ea872f2cd06a61db36785caba027eb9699e744 Mon Sep 17 00:00:00 2001 From: Mark Payne Date: Tue, 24 Nov 2020 14:46:49 -0500 Subject: [PATCH] NIFI-8042: Fixed bug that was escaping Expression Language references for use in a Regular Expression (i.e., Pattern.quote) even though it wasn't being used in a Regular Expression This closes #4685 Signed-off-by: Mike Thomsen --- .../nifi/processors/standard/ReplaceText.java | 3 +- .../processors/standard/TestReplaceText.java | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) 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 58f4f59c10..c3d87f12c8 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 @@ -602,8 +602,7 @@ public class ReplaceText extends AbstractProcessor { @Override public FlowFile replace(FlowFile flowFile, final ProcessSession session, final ProcessContext context, final String evaluateMode, final Charset charset, final int maxBufferSize) { final String replacementValue = context.getProperty(REPLACEMENT_VALUE).evaluateAttributeExpressions(flowFile).getValue(); - final AttributeValueDecorator quotedAttributeDecorator = Pattern::quote; - final String searchValue = context.getProperty(SEARCH_VALUE).evaluateAttributeExpressions(flowFile, quotedAttributeDecorator).getValue(); + final String searchValue = context.getProperty(SEARCH_VALUE).evaluateAttributeExpressions(flowFile).getValue(); if (evaluateMode.equalsIgnoreCase(ENTIRE_TEXT)) { final int flowFileSize = (int) flowFile.getSize(); 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 b3200a8aea..9dac00f58d 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 @@ -31,6 +31,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.regex.Pattern; @@ -53,6 +54,66 @@ public class TestReplaceText { return runner; } + @Test + public void testLiteralReplaceWithExpressionLanguageInSearchEntireText() { + final TestRunner runner = getRunner(); + runner.enqueue("Me, you, and the other", Collections.singletonMap("search.value", "you, and")); + runner.setProperty(ReplaceText.SEARCH_VALUE, "Me, ${search.value}"); + runner.setProperty(ReplaceText.REPLACEMENT_VALUE, "\"Replacement\""); + runner.setProperty(ReplaceText.EVALUATION_MODE, ReplaceText.ENTIRE_TEXT); + runner.setProperty(ReplaceText.REPLACEMENT_STRATEGY, ReplaceText.LITERAL_REPLACE.getValue()); + runner.run(); + + runner.assertAllFlowFilesTransferred(ReplaceText.REL_SUCCESS, 1); + final MockFlowFile out = runner.getFlowFilesForRelationship(ReplaceText.REL_SUCCESS).get(0); + out.assertContentEquals("\"Replacement\" the other"); + } + + @Test + public void testLiteralReplaceWithExpressionLanguageInReplacementEntireText() { + final TestRunner runner = getRunner(); + runner.enqueue("Me, you, and the other", Collections.singletonMap("replacement.value", "us")); + runner.setProperty(ReplaceText.SEARCH_VALUE, "Me, you,"); + runner.setProperty(ReplaceText.REPLACEMENT_VALUE, "With ${replacement.value}"); + runner.setProperty(ReplaceText.EVALUATION_MODE, ReplaceText.ENTIRE_TEXT); + runner.setProperty(ReplaceText.REPLACEMENT_STRATEGY, ReplaceText.LITERAL_REPLACE.getValue()); + runner.run(); + + runner.assertAllFlowFilesTransferred(ReplaceText.REL_SUCCESS, 1); + final MockFlowFile out = runner.getFlowFilesForRelationship(ReplaceText.REL_SUCCESS).get(0); + out.assertContentEquals("With us and the other"); + } + + @Test + public void testLiteralReplaceWithExpressionLanguageInSearchLineByLine() { + final TestRunner runner = getRunner(); + runner.enqueue("Me, you, and the other", Collections.singletonMap("search.value", "you, and")); + runner.setProperty(ReplaceText.SEARCH_VALUE, "Me, ${search.value}"); + runner.setProperty(ReplaceText.REPLACEMENT_VALUE, "\"Replacement\""); + runner.setProperty(ReplaceText.EVALUATION_MODE, ReplaceText.LINE_BY_LINE); + runner.setProperty(ReplaceText.REPLACEMENT_STRATEGY, ReplaceText.LITERAL_REPLACE.getValue()); + runner.run(); + + runner.assertAllFlowFilesTransferred(ReplaceText.REL_SUCCESS, 1); + final MockFlowFile out = runner.getFlowFilesForRelationship(ReplaceText.REL_SUCCESS).get(0); + out.assertContentEquals("\"Replacement\" the other"); + } + + @Test + public void testLiteralReplaceWithExpressionLanguageInReplacementLineByLine() { + final TestRunner runner = getRunner(); + runner.enqueue("Me, you, and the other", Collections.singletonMap("replacement.value", "us")); + runner.setProperty(ReplaceText.SEARCH_VALUE, "Me, you,"); + runner.setProperty(ReplaceText.REPLACEMENT_VALUE, "With ${replacement.value}"); + runner.setProperty(ReplaceText.EVALUATION_MODE, ReplaceText.LINE_BY_LINE); + runner.setProperty(ReplaceText.REPLACEMENT_STRATEGY, ReplaceText.LITERAL_REPLACE.getValue()); + runner.run(); + + runner.assertAllFlowFilesTransferred(ReplaceText.REL_SUCCESS, 1); + final MockFlowFile out = runner.getFlowFilesForRelationship(ReplaceText.REL_SUCCESS).get(0); + out.assertContentEquals("With us and the other"); + } + @Test public void testConfigurationCornerCase() throws IOException { final TestRunner runner = getRunner();