1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Bug 474648 - Wrong arguments are passed to a program in debug mode

Change-Id: Ie9ab74e0142c10ad43891febf910e2fb49b2ec61
Signed-off-by: Sergey Grant <sergey.grant@me.com>
This commit is contained in:
Sergey Grant 2015-12-03 14:27:44 -08:00
parent 8d898be364
commit 8360f715eb
2 changed files with 113 additions and 44 deletions

View file

@ -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]);
}
this(dmc, new String[0]);
}
/** @since 4.0 */
public MIGDBSetArgs(IMIContainerDMContext dmc, String[] arguments) {
super(dmc, null);
/** @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]));
}
}
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);
}
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();
}
}
}

View file

@ -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));
}
/**