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:
parent
8d898be364
commit
8360f715eb
2 changed files with 113 additions and 44 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue