NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
lib/54281: libedit: rl_line_buffer content leaks cross-prompt
>Number: 54281
>Category: lib
>Synopsis: libedit: rl_line_buffer content leaks cross-prompt
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jun 06 21:15:00 +0000 2019
>Originator: Jonathan Perkins
>Release: Sources as of 2019/06/06
>Organization:
Google
>Environment:
>Description:
It appears that rl_line_buffer isn't getting null-terminated consistently when the length shortens. This is particularly observable in tab completion, where users may look at rl_line_buffer to see the full user input.
I'm proposing to null-terminate rl_line_buffer on modification. While rl_end allows the user to determine the end, the null terminator appears to be compatible with how readline is behaving.
The intent is that code like this should work:
const std::string full_line = collected_line_ + std::string(rl_line_buffer);
>How-To-Repeat:
Example code is below. To repro with a binary from it, type "example", press enter, then press tab to trigger completions.
With the current libedit, output should be:
Test> example
Test> example
This is because "example" has leaked cross-prompt and is visible to completion in rl_line_buffer.
With this fix, output should be:
Test> example
Test>
This is because rl_line_buffer gets null-terminated, making rl_line_buffer an empty string (correctly)
Example code:
#include <stdlib.h>
#include <string.h>
#include "readline.h"
static char** DoComplete(const char* text, int start, int end) {
char** results = (char**)malloc(sizeof(*results) * 3);
results[0] = strdup(rl_line_buffer);
results[1] = strdup(rl_line_buffer);
results[2] = nullptr;
return results;
}
int main(int argc, char** argv) {
for (;;) {
char* result = readline("Test> ");
if (result == nullptr) break;
rl_attempted_completion_function = DoComplete;
}
return 0;
}
>Fix:
--- old/libedit/readline.c
+++ new/libedit/readline.c
@@ -2231,6 +2231,7 @@ static void
rl_point = (int)(li->cursor - li->buffer);
rl_end = (int)(li->lastchar - li->buffer);
+ rl_line_buffer[rl_end] = '\0';
}
void
Home |
Main Index |
Thread Index |
Old Index