-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
gh-74616: Raise ValueError in case of NULL in input prompt #1738
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Python/bltinmodule.c
Outdated
promptstr = ""; | ||
} | ||
if (PyBytes_GET_SIZE(po) != strlen(promptstr)) { | ||
PyErr_SetString(PyExc_ValueError, | ||
"input prompt has NULL character"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about "input: prompt string cannot contain null characters"
? "null" is more common in existing error messages, but "NUL" with one L is also used, since that's the ASCII name of character. NULL
refers to the C pointer constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I will modify it for the same.
6a47483
to
b0b45fd
Compare
Doc/library/functions.rst
Outdated
@@ -680,6 +680,15 @@ are always available. They are listed here in alphabetical order. | |||
If the :mod:`readline` module was loaded, then :func:`input` will use it | |||
to provide elaborate line editing and history features. | |||
|
|||
.. versionchanged:: 3.7 | |||
If the input prompt string has a NULL character, then it will raise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NULL means a null pointer in C. Use "a null character" for consistency with other documentation.
But actually I think this change doesn't need special mentioning in the documentation. This is just a bugfix. A null character is prohibited in many other APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, will remove this docs update.
Python/bltinmodule.c
Outdated
@@ -1976,9 +1976,15 @@ builtin_input_impl(PyObject *module, PyObject *prompt) | |||
promptstr = PyBytes_AS_STRING(po); | |||
} | |||
else { | |||
po = NULL; | |||
po = PyBytes_FromString(""); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can raise an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, I will do a check for NULL case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually I don't need this anymore for the change as mentioned the comment below.
b0b45fd
to
fa1a030
Compare
If the input prompt to the builtin input function has any null character, then raise ValueError.
fa1a030
to
72c5af2
Compare
Lib/test/test_readline.py
Outdated
@@ -127,6 +127,13 @@ def test_init(self): | |||
input() | |||
print("History length:", readline.get_current_history_length()) | |||
""" | |||
auto_history_script_with_null = """\ | |||
import readline | |||
readline.set_auto_history({}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is readline history related to this issue? Does the test work if remove calls of set_auto_history
and get_current_history_length
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect the readline module is not needed at all. Perhaps the test would be better off in test_builtin.py. There are already some tests there in the PtyTests class that call input on a terminal, so you may be able to use them for inspiration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change, if general, introduces a regression. The doc for input(prompt) says "If the prompt argument is present, it is written to standard output without a trailing newline." The handling of the prompt is up to stdout.write and thence physical displays devices. Python does not specify what happens with any particular character, including \r, \t, and astral chars. [This is an abbreviation of my 2017-05-27 posts on the issue]
To try and help move older pull requests forward, we are going through and backfilling 'awaiting' labels on pull requests that are lacking the label. Based on the current reviews, the best we can tell in an automated fashion is that a core developer requested changes to be made to this pull request. If/when the requested changes have been made, please leave a comment that says, |
This PR is stale because it has been open for 30 days with no activity. |
This PR is stale because it has been open for 30 days with no activity. |
@terryjreedy - are you saying that this PR should be rejected, or did I misunderstand? |
Yes, to me the patch is wrong. The doc still says "If the prompt argument is present, it is written to standard output without a trailing newline. " The issue OP, ghost, merely noted that the prompt was truncated. I believe 'ghost' wanted it to not be truncated. To me, raising instead of writing something is worse. It is not normal for Python to check strings for null. Print and sys.stdout.write and sys.stderr.write do not. From my testing of builtin functions, only the filename in open and compile is. The attr functions and int and iter do not. Eryk says the prompt goes to stderr on terminals. If this is considered correct, then the doc should be changed. |
If a string is passed to C as a null-terminated string,
The underlying calls to POSIX
If The default implementation of You can examine the different behavior on a Unix system by executing a test script with the single line Footnotes
|
It would seem then that calling sys.stdout.write('prompt') (or sys.stderr? when appropriate?) and then PyOS_Readline(), with no prompt, would solve the truncation issue. As for the destination, I am just suggesting adding 'or error' to the current doc to match the behavior. |
Unfortunately GNU Readline needs to be passed the prompt in order to set the margin for editing. Without it, for example, pressing the home key will move the cursor to the first column of the terminal instead of the first column after the prompt. |
In Python interface to OS or other libraries an error is raised if the underlying function does not support embedded NULs (for example if it takes argument as a null-terminated string And since the readline API accepts argument as null-terminated string, we should ensure that it does not contain embedded NULs. |
Co-authored-by: Eryk Sun <[email protected]>
Eryk's cursor control (prompt avoidance) issue, which IDLE has now, convinced me to drop my objection to the code change. |
@serhiy-storchaka, do you think |
Good question. Since |
This PR is stale because it has been open for 30 days with no activity. |
The objection was dropped.
…rompt (pythonGH-1738) If the input prompt to the builtin input function on terminal has any null character, then raise ValueError instead of silently truncating it. Co-authored-by: Serhiy Storchaka <[email protected]>
…rompt (pythonGH-1738) If the input prompt to the builtin input function on terminal has any null character, then raise ValueError instead of silently truncating it. Co-authored-by: Serhiy Storchaka <[email protected]>
If the input prompt to the builtin input function has any NULL
character, then raise ValueError.