From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id CE95E385829B for ; Mon, 4 Nov 2024 14:46:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org CE95E385829B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org CE95E385829B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730731588; cv=none; b=llizWDK0UdQ1+PHfWKypXu3lD4f6ZWQ7FVlyIxMT7yi4n3vhPl2zkzURV+wlnXgokCPgl5B0sgWSf5Xf8hBdKUVsrxeVUW/H/wmTmIZlC893qpr5dzhOCe1AMe1BJ/3Jmwjs8LTDDzd9lZRWKMTmP7h5Slawl160zEysNXRX+Dw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1730731588; c=relaxed/simple; bh=vg69YUCshvT5FGeA3kBB+jF+V5aSxymbPRgJOa26f4I=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=nZMNBRU2Q/KwK2l+xPyt0C2Xj4+drjHfrhp/0mdQAOBgBi/bNjr01NOSNtUklX0WAh1KHQNon2YvBUVfeMT+XW7zeDHi8WuF8C4VFKdjiYdnITmTDfvCeOTeKlSLcCRuYiG9lbNXE99cPSWJVrLzh0zGO2ehIcSwmOzJhTVJwUU= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1730731577; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3P0WeDY8+iPax0ScYzG24bQ4gL0D5VLhIEu9K5iwtzY=; b=fiI1Go6XTYK8o3nxcshWY3N6TCry1gZKvZ48RKim8JFta8hiKqK+GYVHTwIAAxd/RzCFy4 FCcWeWHTGhgPqsyB932FGXZIFDuT6SGAmqm1KBf6d1NxqPzQYsunFcEYPOl5I2ac5qamDV x2qMuguXjZYOVk9SUs6jhAzd0tYhZuw= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-433-MI6JNNihMtmIz0HjqJR1uw-1; Mon, 04 Nov 2024 09:46:16 -0500 X-MC-Unique: MI6JNNihMtmIz0HjqJR1uw-1 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4315ad4938fso27273365e9.0 for ; Mon, 04 Nov 2024 06:46:16 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730731574; x=1731336374; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3P0WeDY8+iPax0ScYzG24bQ4gL0D5VLhIEu9K5iwtzY=; b=p5rTlZCisTnhqhKkZgapNW+rfMPErlZNbnz5vp5MH87KWd2bFz/Y8SW9oAVxQLD6xl sI/UHerEh0gB7eEmLBc8DT/DZdL6ow36vIx8XxKxuQOr+HSd9HoADEgYgSJEh0CRYf24 2/+4qIYxNf9tquYcR2eWLr6i90N818eR5x095KtGUYm9Q9Km7hYmLNijBFG54UsEE97S SvBUhYpDIiMAyCcZVKjkyPK7oHh82PYSUKhvyVoVxRvuKv4Y7kT0mU40f2bGwmVrENJx OutX4dWDyixoio9QI61hiu81ZlHhX7H4j8NrwdY5glfTS1tffVdt6e4sz/kTI2dF8lA2 96wA== X-Gm-Message-State: AOJu0Yy93N/sjzWeUtlr6Yl5ogy/ads3jB/g1+n+ow0V9Ma0BrdcQR1c k3Zg1P5tyIirTWXL24buOm+MC+n5yb7N6p6qILpoI7UtN3YILhWrtgI+d+4Af96WkuSNV/mVr+W ack6G7dd+PiuUsKZJrB5knNzrg1Fv67G9BbzgWI3xVG9x19EJyH+/K9I9yvIW7VKbbPP8qKHDJ/ cQ2XA/+O/NTJbfL8qZdSkdT6DgwADTHr7LhGDnrr4a7So= X-Received: by 2002:a05:600c:19c8:b0:430:54a4:5b03 with SMTP id 5b1f17b1804b1-4319ac6fad6mr262613065e9.6.1730731573642; Mon, 04 Nov 2024 06:46:13 -0800 (PST) X-Google-Smtp-Source: AGHT+IG/LQqMqadbdQnhCsdJoQ1jqMBEFGzUe6+z++QfDRsP5H5KWOhWJRaczjCxzrjuAk/PglKEjQ== X-Received: by 2002:a05:600c:19c8:b0:430:54a4:5b03 with SMTP id 5b1f17b1804b1-4319ac6fad6mr262612765e9.6.1730731573135; Mon, 04 Nov 2024 06:46:13 -0800 (PST) Received: from localhost (197.209.200.146.dyn.plus.net. [146.200.209.197]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-431bd9ca818sm185410335e9.40.2024.11.04.06.46.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Nov 2024 06:46:12 -0800 (PST) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess , Eli Zaretskii Subject: [PATCHv2 08/14] gdb/python: change escaping rules when setting arguments Date: Mon, 4 Nov 2024 14:45:52 +0000 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII"; x-default=true X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: It is possible to set an inferior's arguments through the Python API by assigning to the gdb.Inferior.arguments attribute. This attribute can be assigned a string, in which case the string is taken verbatim as the inferior's argument string. Or this attribute can be assigned a sequence, in which case the members of the sequence are combined (with some escaping applied) to create the inferior's argument string. When assigning from a sequence, all special shell characters in each argument are escaped, I suspect the reasons for this are mostly accidental. When the gdb.Inferior.arguments attribute was introduced in commit: commit 3153113252f3b949a159439a17e88af8ff0dce30 Date: Mon May 1 13:53:59 2023 -0600 Add attributes and methods to gdb.Inferior GDB's inferior::set_args method called construct_inferior_arguments, and construct_inferior_arguments only offered one form of escaping, all special shell characters were escaped. The commit message makes no comments for or against escaping of special shell characters, and no tests were added that checked this behaviour. All of this leads me to think that the handling of special shell characters wasn't really considered too much ... after all, GDB was already a little iffy about its escape handling (hence this series). I would like to consider how escaping should be handled. I'm not sure we got this quite right initially. Consider this case: (gdb) python gdb.selected_inferior().arguments = ['$VAR'] (gdb) show args Argument list to give program being debugged when it is started is "\$VAR". This means that when the inferior is run it will see literal '$VAR' as its argument. If instead, the user wants to pass the shell expanded value of $VAR to the inferior, there's no way to achieve this result using the sequence assignment method. Instead the user has to manually combine the arguments, and assign a single string. In this commit I propose that we change this behaviour so that we instead see this: (gdb) python gdb.selected_inferior().arguments = ['$VAR'] (gdb) show args Argument list to give program being debugged when it is started is "$VAR". Now the '$' character is not escaped. If the inferior is started under a shell then the user will see the shell expanded value of '$VAR'. Of course, if the user wants to pass a literal '$VAR' (with no expansion) then they can do: (gdb) python gdb.selected_inferior().arguments = ['\$VAR'] This actually feels more natural to me, the user writes the argument as they would present it to a shell. So, after this commit, GDB only escapes those characters that are special to GDB, that is, white space and quote characters. It is important to understand that this is an Python API breaking change, and this could impact existing user scripts. My hope is that this is enough of an edge case that we'll not inconvenience too many users. I'd rather not have too, but I did have a couple of ideas for approaches that would retain the existing API. We could add an Inferior method (in the Python API) for setting the inferior arguments, this method could then apply the new quoting rules described above. Or we could add a second attribute, with a slightly different name, which, when assigned too would _also_ update the inferior arguments, but would apply the new quoting rules. Both of these would work, but I don't think these would be ideal. I'd really like to try to just change the quoting rules and hope we don't upset too many people.... but I'm open to feedback on this. There are tests for the updated functionality, and I've updated the docs and added a NEWS entry. Reviewed-By: Eli Zaretskii --- gdb/NEWS | 4 +++ gdb/doc/python.texi | 7 +++-- gdb/python/py-inferior.c | 2 +- gdb/testsuite/gdb.python/py-inferior.exp | 36 ++++++++++++++++++++---- 4 files changed, 41 insertions(+), 8 deletions(-) diff --git a/gdb/NEWS b/gdb/NEWS index 42b8a88fd8a..7c3c02a4cd3 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -56,6 +56,10 @@ ** Added gdb.record.clear. Clears the trace data of the current recording. This forces re-decoding of the trace for successive commands. + ** When assigning a sequence to gdb.Inferior.arguments, only quote + and whitespace characters will be escaped. Everything else will + be left unmodified. + * Debugger Adapter Protocol changes ** The "scopes" request will now return a scope holding global diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 22f0e6c6d0a..de6963f881a 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -3581,8 +3581,11 @@ Either a string or a sequence of strings can be assigned to this attribute. When a string is assigned, it is assumed to have any -necessary quoting for the shell; when a sequence is assigned, the -quoting is applied by @value{GDBN}. +necessary quoting for the shell; when a sequence is assigned, quoting +is applied by @value{GDBN} so that the individual strings can be +concatenated into a single string, with a single space between each +argument. This means that shell quote characters and whitespace +characters will be escaped. @end defvar A @code{gdb.Inferior} object has the following methods: diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index 3a5bf9344f6..88d80908575 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -929,7 +929,7 @@ infpy_set_args (PyObject *self, PyObject *value, void *closure) for (const auto &arg : args) argvec.push_back (arg.get ()); gdb::array_view view (argvec.data (), argvec.size ()); - inf->inferior->set_args (view, true); + inf->inferior->set_args (view, false); } else { diff --git a/gdb/testsuite/gdb.python/py-inferior.exp b/gdb/testsuite/gdb.python/py-inferior.exp index 58475bded0f..b54a3c9e5ca 100644 --- a/gdb/testsuite/gdb.python/py-inferior.exp +++ b/gdb/testsuite/gdb.python/py-inferior.exp @@ -480,11 +480,37 @@ gdb_test "show args" \ [string_to_regexp "Argument list to give program being debugged when it is started is \"a b c\"."] \ "show args from string" -gdb_test_no_output "python gdb.selected_inferior().arguments = \['a', 'b c'\]" \ - "set arguments from list" -gdb_test "show args" \ - [string_to_regexp "Argument list to give program being debugged when it is started is \"a b\\ c\"."] \ - "show args from list" +# Test setting inferior arguments from a Python list. INPUT is a +# single string that contains the Python list, this is inserted into +# the argument setting command, and should include the surrouning +# square brackets. +# +# The OUTPUT is the string that describes the arguments as GDB will +# have stored them within the inferior, as seen in the 'show args' +# command output. OUTPUT should include the surrounding quotes. +# OUTPUT will be passed through string_to_regexp, so should be a plain +# string, not a regexp. +proc test_setting_arguments_from_list { input output } { + with_test_prefix "input: ${input}" { + gdb_test_no_output "python gdb.selected_inferior().arguments = ${input}" \ + "set arguments from list" + gdb_test "show args" \ + [string_to_regexp \ + "Argument list to give program being debugged when it is started is ${output}."] \ + "show args from list" + } +} + +# Test setting inferior arguments from a list. Try to hit all the +# potentially problematic cases. Notice that shell characters are not +# automatically quoted, if a user wants a shell character quoted then +# they must do that themselves. +test_setting_arguments_from_list "\['a', 'b c'\]" "\"a b\\ c\"" +test_setting_arguments_from_list "\[' ', '\\t', '\\n']" "\"\\ \\\t '\r\n'\"" +test_setting_arguments_from_list "\['', '']" "\"'' ''\"" +test_setting_arguments_from_list "\['\"']" "\"\\\"\"" +test_setting_arguments_from_list "\[\"'\"]" "\"\\\'\"" +test_setting_arguments_from_list "\[\"\$VAR\", \";\"]" "\"\$VAR ;\"" gdb_test_no_output "python gdb.selected_inferior().clear_env()" \ "clear environment" -- 2.25.4