This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/master by this push:
new 7e2f28d932 Replace in string does not handle \ as expected #2066
new 993655b3df Merge pull request #2114 from nadment/2066
7e2f28d932 is described below
commit 7e2f28d9325600929946b4fb42c1f659d7d39b86
Author: Nicolas Adment <[email protected]>
AuthorDate: Thu Dec 29 22:30:17 2022 +0100
Replace in string does not handle \ as expected #2066
---
.../0026-replace-in-string-with-backslash.hpl | 169 +++++++++++++++++++++
.../golden-replace-in-string-with-backslash.csv | 3 +
.../transforms/main-0026-replace-in-string.hwf | 13 +-
.../golden-replace-in-string-with-backslash.json | 32 ++++
...0026-replace-in-string-with-backslash UNIT.json | 38 +++++
.../transforms/replacestring/ReplaceString.java | 11 +-
6 files changed, 259 insertions(+), 7 deletions(-)
diff --git
a/integration-tests/transforms/0026-replace-in-string-with-backslash.hpl
b/integration-tests/transforms/0026-replace-in-string-with-backslash.hpl
new file mode 100644
index 0000000000..33b863bba0
--- /dev/null
+++ b/integration-tests/transforms/0026-replace-in-string-with-backslash.hpl
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+-->
+<pipeline>
+ <info>
+ <name>0026-replace-in-string-with-backslash</name>
+ <name_sync_with_filename>Y</name_sync_with_filename>
+ <description/>
+ <extended_description/>
+ <pipeline_version/>
+ <pipeline_type>Normal</pipeline_type>
+ <pipeline_status>0</pipeline_status>
+ <parameters>
+ <parameter>
+ <name>REPLACE_PARAM</name>
+ <default_value>xx\zz</default_value>
+ <description>Variable with backslash</description>
+ </parameter>
+ </parameters>
+ <capture_transform_performance>N</capture_transform_performance>
+
<transform_performance_capturing_delay>1000</transform_performance_capturing_delay>
+
<transform_performance_capturing_size_limit>100</transform_performance_capturing_size_limit>
+ <created_user>-</created_user>
+ <created_date>2022/11/27 16:28:58.618</created_date>
+ <modified_user>-</modified_user>
+ <modified_date>2022/11/27 16:28:58.618</modified_date>
+ </info>
+ <notepads>
+ </notepads>
+ <order>
+ <hop>
+ <from>sample data</from>
+ <to>Replace in string</to>
+ <enabled>Y</enabled>
+ </hop>
+ <hop>
+ <from>Replace in string</from>
+ <to>Verify</to>
+ <enabled>Y</enabled>
+ </hop>
+ </order>
+ <transform>
+ <name>Replace in string</name>
+ <type>ReplaceString</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <fields>
+ <field>
+ <case_sensitive>N</case_sensitive>
+ <in_stream_name>value_variable</in_stream_name>
+ <is_unicode>N</is_unicode>
+ <replace_by_string>${REPLACE_PARAM}</replace_by_string>
+ <replace_string>backslash</replace_string>
+ <set_empty_string>N</set_empty_string>
+ <use_regex>N</use_regex>
+ <whole_word>N</whole_word>
+ </field>
+ <field>
+ <case_sensitive>N</case_sensitive>
+ <in_stream_name>value_field</in_stream_name>
+ <is_unicode>N</is_unicode>
+ <replace_field_by_string>replaceBy</replace_field_by_string>
+ <replace_string>backslash</replace_string>
+ <set_empty_string>N</set_empty_string>
+ <use_regex>N</use_regex>
+ <whole_word>N</whole_word>
+ </field>
+ </fields>
+ <attributes/>
+ <GUI>
+ <xloc>288</xloc>
+ <yloc>96</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>Verify</name>
+ <type>Dummy</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <attributes/>
+ <GUI>
+ <xloc>464</xloc>
+ <yloc>96</yloc>
+ </GUI>
+ </transform>
+ <transform>
+ <name>sample data</name>
+ <type>DataGrid</type>
+ <description/>
+ <distribute>Y</distribute>
+ <custom_distribution/>
+ <copies>1</copies>
+ <partitioning>
+ <method>none</method>
+ <schema_name/>
+ </partitioning>
+ <data>
+ <line>
+ <item>try to specify the backslash</item>
+ <item>try to specify the backslash</item>
+ <item>single \ backslash</item>
+ </line>
+ <line>
+ <item>method to replace the backslash</item>
+ <item>method to replace the backslash</item>
+ <item>double \\ backslash</item>
+ </line>
+ </data>
+ <fields>
+ <field>
+ <length>-1</length>
+ <precision>-1</precision>
+ <set_empty_string>N</set_empty_string>
+ <name>value_variable</name>
+ <type>String</type>
+ </field>
+ <field>
+ <length>-1</length>
+ <precision>-1</precision>
+ <set_empty_string>N</set_empty_string>
+ <name>value_field</name>
+ <type>String</type>
+ </field>
+ <field>
+ <length>-1</length>
+ <precision>-1</precision>
+ <set_empty_string>N</set_empty_string>
+ <name>replaceBy</name>
+ <type>String</type>
+ </field>
+ </fields>
+ <attributes/>
+ <GUI>
+ <xloc>128</xloc>
+ <yloc>96</yloc>
+ </GUI>
+ </transform>
+ <transform_error_handling>
+ </transform_error_handling>
+ <attributes/>
+</pipeline>
diff --git
a/integration-tests/transforms/datasets/golden-replace-in-string-with-backslash.csv
b/integration-tests/transforms/datasets/golden-replace-in-string-with-backslash.csv
new file mode 100644
index 0000000000..7572c681f1
--- /dev/null
+++
b/integration-tests/transforms/datasets/golden-replace-in-string-with-backslash.csv
@@ -0,0 +1,3 @@
+value_variable,value_field,replaceBy
+try to specify the xx\zz,try to specify the single \ backslash,single \
backslash
+method to replace the xx\zz,method to replace the double \\ backslash,double
\\ backslash
diff --git a/integration-tests/transforms/main-0026-replace-in-string.hwf
b/integration-tests/transforms/main-0026-replace-in-string.hwf
index c6a64bb40b..04a293a334 100644
--- a/integration-tests/transforms/main-0026-replace-in-string.hwf
+++ b/integration-tests/transforms/main-0026-replace-in-string.hwf
@@ -35,14 +35,14 @@ limitations under the License.
<description/>
<type>SPECIAL</type>
<attributes/>
- <repeat>N</repeat>
- <schedulerType>0</schedulerType>
- <intervalSeconds>0</intervalSeconds>
- <intervalMinutes>60</intervalMinutes>
+ <DayOfMonth>1</DayOfMonth>
<hour>12</hour>
+ <intervalMinutes>60</intervalMinutes>
+ <intervalSeconds>0</intervalSeconds>
<minutes>0</minutes>
+ <repeat>N</repeat>
+ <schedulerType>0</schedulerType>
<weekDay>1</weekDay>
- <DayOfMonth>1</DayOfMonth>
<parallel>N</parallel>
<xloc>128</xloc>
<yloc>80</yloc>
@@ -57,6 +57,9 @@ limitations under the License.
<test_name>
<name>0026-replace-in-string UNIT</name>
</test_name>
+ <test_name>
+ <name>0026-replace-in-string-with-backslash UNIT</name>
+ </test_name>
</test_names>
<parallel>N</parallel>
<xloc>336</xloc>
diff --git
a/integration-tests/transforms/metadata/dataset/golden-replace-in-string-with-backslash.json
b/integration-tests/transforms/metadata/dataset/golden-replace-in-string-with-backslash.json
new file mode 100644
index 0000000000..2e31fd46e0
--- /dev/null
+++
b/integration-tests/transforms/metadata/dataset/golden-replace-in-string-with-backslash.json
@@ -0,0 +1,32 @@
+{
+ "base_filename": "golden-replace-in-string-with-backslash.csv",
+ "name": "golden-replace-in-string-with-backslash",
+ "description": "",
+ "dataset_fields": [
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_name": "value_variable",
+ "field_format": ""
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_name": "value_field",
+ "field_format": ""
+ },
+ {
+ "field_comment": "",
+ "field_length": -1,
+ "field_type": 2,
+ "field_precision": -1,
+ "field_name": "replaceBy",
+ "field_format": ""
+ }
+ ],
+ "folder_name": ""
+}
\ No newline at end of file
diff --git
a/integration-tests/transforms/metadata/unit-test/0026-replace-in-string-with-backslash
UNIT.json
b/integration-tests/transforms/metadata/unit-test/0026-replace-in-string-with-backslash
UNIT.json
new file mode 100644
index 0000000000..b76747f33c
--- /dev/null
+++
b/integration-tests/transforms/metadata/unit-test/0026-replace-in-string-with-backslash
UNIT.json
@@ -0,0 +1,38 @@
+{
+ "variableValues": [],
+ "database_replacements": [],
+ "autoOpening": true,
+ "basePath": "",
+ "golden_data_sets": [
+ {
+ "field_mappings": [
+ {
+ "transform_field": "value_variable",
+ "data_set_field": "value_variable"
+ },
+ {
+ "transform_field": "value_field",
+ "data_set_field": "value_field"
+ },
+ {
+ "transform_field": "replaceBy",
+ "data_set_field": "replaceBy"
+ }
+ ],
+ "field_order": [
+ "value_variable",
+ "value_field",
+ "replaceBy"
+ ],
+ "data_set_name": "golden-replace-in-string-with-backslash",
+ "transform_name": "Verify"
+ }
+ ],
+ "input_data_sets": [],
+ "name": "0026-replace-in-string-with-backslash UNIT",
+ "description": "",
+ "persist_filename": "",
+ "trans_test_tweaks": [],
+ "pipeline_filename": "./0026-replace-in-string-with-backslash.hpl",
+ "test_type": "UNIT_TEST"
+}
\ No newline at end of file
diff --git
a/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceString.java
b/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceString.java
index ae66cb14ee..4b198b0b29 100644
---
a/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceString.java
+++
b/plugins/transforms/replacestring/src/main/java/org/apache/hop/pipeline/transforms/replacestring/ReplaceString.java
@@ -115,7 +115,13 @@ public class ReplaceString extends
BaseTransform<ReplaceStringMeta, ReplaceStrin
return data.replaceByString[index];
}
- return getInputRowMeta().getString(row, data.replaceFieldIndex[index]);
+ String str = getInputRowMeta().getString(row,
data.replaceFieldIndex[index]);
+
+ // Escape the regex pattern backslash
+ if ( str!=null ) {
+ str = str.replace("\\","\\\\");
+ }
+ return str;
}
synchronized Object[] handleOneRow(IRowMeta rowMeta, Object[] row) throws
HopException {
@@ -209,7 +215,8 @@ public class ReplaceString extends
BaseTransform<ReplaceStringMeta, ReplaceStrin
}
} else {
data.replaceFieldIndex[i] = -1;
- data.replaceByString[i] =
Const.NVL(resolve(field.getReplaceByString()), "");
+ // Escape the regex pattern backslash
+ data.replaceByString[i] =
Const.NVL(resolve(field.getReplaceByString()), "").replace("\\","\\\\");
}
data.setEmptyString[i] = field.isSettingEmptyString();
}