Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey Grant2015-12-03 22:27:44 +0000
committerSergey Grant2015-12-03 22:43:31 +0000
commit8360f715ebbdb5fccc2dfa0e262766b70dfffb88 (patch)
tree1947331eb8ab336f016ecc9e56b6a81bdd7b4e5d
parent8d898be36427e71f47a32e08f8f2c219f369d2a8 (diff)
downloadorg.eclipse.cdt-8360f715ebbdb5fccc2dfa0e262766b70dfffb88.tar.gz
org.eclipse.cdt-8360f715ebbdb5fccc2dfa0e262766b70dfffb88.tar.xz
org.eclipse.cdt-8360f715ebbdb5fccc2dfa0e262766b70dfffb88.zip
Bug 474648 - Wrong arguments are passed to a program in debug mode
Change-Id: Ie9ab74e0142c10ad43891febf910e2fb49b2ec61 Signed-off-by: Sergey Grant <sergey.grant@me.com>
-rw-r--r--dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetArgs.java73
-rw-r--r--dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchConfigurationAndRestartTest.java88
2 files changed, 115 insertions, 46 deletions
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetArgs.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetArgs.java
index 620de2d873e..8152b46825b 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetArgs.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/command/commands/MIGDBSetArgs.java
@@ -7,12 +7,13 @@
*
* Contributors:
* Ericsson - Initial API and implementation
- * Sergey Prigogin (Google)
+ * Sergey Prigogin (Google)
* Marc Khouzam (Ericsson) - Support empty arguments (bug 412471)
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.commands;
+import java.util.ArrayList;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
/**
@@ -23,25 +24,55 @@ import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
*/
public class MIGDBSetArgs extends MIGDBSet {
- /** @since 4.0 */
+ /** @since 4.0 */
public MIGDBSetArgs(IMIContainerDMContext dmc) {
- this(dmc, new String[0]);
- }
-
- /** @since 4.0 */
- public MIGDBSetArgs(IMIContainerDMContext dmc, String[] arguments) {
- super(dmc, null);
-
- String[] cmdArray = new String[arguments.length + 1];
- cmdArray[0] = "args"; //$NON-NLS-1$
- for (int i = 0; i < arguments.length; i++) {
- if (arguments[i].isEmpty()) {
- // An empty parameter can be passed with two single quotes
- cmdArray[i + 1] = "''"; //$NON-NLS-1$
- } else {
- cmdArray[i + 1] = arguments[i];
- }
- }
- setParameters(cmdArray);
- }
+ this(dmc, new String[0]);
+ }
+
+ /** @since 4.0 */
+ public MIGDBSetArgs(IMIContainerDMContext dmc, String[] arguments) {
+ super(dmc, null);
+ fParameters = new ArrayList<Adjustable>();
+ fParameters.add(new MIStandardParameterAdjustable("args")); //$NON-NLS-1$
+ for (int i = 0; i < arguments.length; i++) {
+ fParameters.add(new MIArgumentAdjustable(arguments[i]));
+ }
+ }
+
+ private static class MIArgumentAdjustable extends MICommandAdjustable {
+
+ public MIArgumentAdjustable(String value) {
+ super(value);
+ }
+
+ @Override
+ public String getAdjustedValue() {
+ // Replace and concatenate all occurrences of:
+ // ' with "'"
+ // (as ' is used to surround everything else
+ // it has to be quoted or escaped)
+ // newline character with $'\n'
+ // (\n is treated literally within quotes or
+ // as just 'n' otherwise, whilst supplying
+ // the newline character literally ends the command)
+ // Anything in between and around these occurrences
+ // is surrounded by single quotes.
+ // (to prevent bash from carrying out substitutions
+ // or running arbitrary code with backticks or $())
+ StringBuilder builder = new StringBuilder();
+ builder.append('\'');
+ for (int j = 0; j < value.length(); j++) {
+ char c = value.charAt(j);
+ if (c == '\'') {
+ builder.append("'\"'\"'"); //$NON-NLS-1$
+ } else if (c == '\n') {
+ builder.append("'$'\\n''"); //$NON-NLS-1$
+ } else {
+ builder.append(c);
+ }
+ }
+ builder.append('\'');
+ return builder.toString();
+ }
+ }
}
diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchConfigurationAndRestartTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchConfigurationAndRestartTest.java
index e59f3ea2794..e8ec515d434 100644
--- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchConfigurationAndRestartTest.java
+++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/LaunchConfigurationAndRestartTest.java
@@ -552,20 +552,12 @@ public class LaunchConfigurationAndRestartTest extends BaseTestCase {
fExpService.getFormattedValueContext(argcDmc, MIExpressions.DETAILS_FORMAT), rm);
}
};
- try {
- fExpService.getExecutor().execute(query);
- FormattedValueDMData value = query.get(500, TimeUnit.MILLISECONDS);
+ fExpService.getExecutor().execute(query);
+ FormattedValueDMData value = query.get(500, TimeUnit.MILLISECONDS);
- // Argc should be 2: the program name and the one arguments
- assertTrue("Expected 2 but got " + value.getFormattedValue(),
- value.getFormattedValue().trim().equals("2"));
- } catch (InterruptedException e) {
- fail(e.getMessage());
- } catch (ExecutionException e) {
- fail(e.getCause().getMessage());
- } catch (TimeoutException e) {
- fail(e.getMessage());
- }
+ // Argc should be 2: the program name and the one arguments
+ assertTrue("Expected 2 but got " + value.getFormattedValue(),
+ value.getFormattedValue().trim().equals("2"));
// Check that argv is also correct.
final IExpressionDMContext argvDmc = SyncUtil.createExpression(stoppedEvent.getDMContext(), "argv[argc-1]");
@@ -576,18 +568,64 @@ public class LaunchConfigurationAndRestartTest extends BaseTestCase {
fExpService.getFormattedValueContext(argvDmc, MIExpressions.DETAILS_FORMAT), rm);
}
};
- try {
- fExpService.getExecutor().execute(query2);
- FormattedValueDMData value = query2.get(500, TimeUnit.MILLISECONDS);
- assertTrue("Expected \"" + argumentUsedByGDB + "\" but got " + value.getFormattedValue(),
- value.getFormattedValue().trim().endsWith(argumentUsedByGDB));
- } catch (InterruptedException e) {
- fail(e.getMessage());
- } catch (ExecutionException e) {
- fail(e.getCause().getMessage());
- } catch (TimeoutException e) {
- fail(e.getMessage());
- }
+ fExpService.getExecutor().execute(query2);
+ value = query2.get(500, TimeUnit.MILLISECONDS);
+ assertTrue("Expected \"" + argumentUsedByGDB + "\" but got " + value.getFormattedValue(),
+ value.getFormattedValue().trim().endsWith(argumentUsedByGDB));
+ }
+
+ /**
+ * This test will tell the launch to set some more arguments for the program. We will
+ * then check that the program has the same arguments.
+ * See bug 474648
+ */
+ @Test
+ public void testSettingArgumentsWithSpecialSymbols() throws Throwable {
+ // Test that arguments are parsed correctly:
+ // The string provided by the user is split into arguments on spaces
+ // except for those inside quotation marks, double or single.
+ // Any character within quotation marks or after the backslash character
+ // is treated literally, whilst these special characters have to be
+ // escaped explicitly to be recorded.
+ // All other characters including semicolons, backticks, pipes, dollars and newlines
+ // must be treated literally.
+ String argumentToPreserveSpaces = "--abc=\"x;y;z\nsecondline: \"`date`$PS1\"`date | wc`\"";
+ String argumentUsedByGDB = "\"--abc=x;y;z\\nsecondline: `date`$PS1`date | wc`\"";
+
+ setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_ARGUMENTS, argumentToPreserveSpaces);
+ doLaunch();
+
+ MIStoppedEvent stoppedEvent = getInitialStoppedEvent();
+
+ // Check that argc is correct
+ final IExpressionDMContext argcDmc = SyncUtil.createExpression(stoppedEvent.getDMContext(), "argc");
+ Query<FormattedValueDMData> query = new Query<FormattedValueDMData>() {
+ @Override
+ protected void execute(DataRequestMonitor<FormattedValueDMData> rm) {
+ fExpService.getFormattedExpressionValue(
+ fExpService.getFormattedValueContext(argcDmc, MIExpressions.DETAILS_FORMAT), rm);
+ }
+ };
+ fExpService.getExecutor().execute(query);
+ FormattedValueDMData value = query.get(500, TimeUnit.MILLISECONDS);
+
+ // Argc should be 2: the program name and the four arguments.
+ assertTrue("Expected 2 but got " + value.getFormattedValue(),
+ value.getFormattedValue().trim().equals("2"));
+
+ // Check that argv is also correct.
+ final IExpressionDMContext argvDmc = SyncUtil.createExpression(stoppedEvent.getDMContext(), "argv[argc-1]");
+ Query<FormattedValueDMData> query2 = new Query<FormattedValueDMData>() {
+ @Override
+ protected void execute(DataRequestMonitor<FormattedValueDMData> rm) {
+ fExpService.getFormattedExpressionValue(
+ fExpService.getFormattedValueContext(argvDmc, MIExpressions.DETAILS_FORMAT), rm);
+ }
+ };
+ fExpService.getExecutor().execute(query2);
+ value = query2.get(500, TimeUnit.MILLISECONDS);
+ assertTrue("Expected \"" + argumentUsedByGDB + "\" but got " + value.getFormattedValue(),
+ value.getFormattedValue().endsWith(argumentUsedByGDB));
}
/**

Back to the top