Skip to content
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

readline.line automatically escapes input #45950

Open
albertopasqualetto opened this issue Dec 22, 2022 · 8 comments
Open

readline.line automatically escapes input #45950

albertopasqualetto opened this issue Dec 22, 2022 · 8 comments

Comments

@albertopasqualetto
Copy link

Version

18.12.0

Platform

Microsoft Windows NT 10.0.22621.0 x64

Subsystem

readline

What steps will reproduce the bug?

Use readline and access its line variable.

rl.line

How often does it reproduce? Is there a required condition?

No response

What is the expected behavior?

No response

What do you see instead?

I see that if I input \n, then it is automatically escaped with \\n, is it possible to disable this behavior and get \n?

Additional information

I am not sure if this behavior is something wanted. If so, then I am asking if there is an alternative to get the non-escaped character. (\n)

@bnoordhuis
Copy link
Member

Can you post a test case? I'm fairly sure no escaping takes place inside the readline module; you're probably looking at something that was ran through e.g. util.format().

@albertopasqualetto
Copy link
Author

I write something random which contains \n and then ^C.

This is the code:

const readline = require('node:readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on('pause', () => {
	console.log()
	console.log('Line: ' + rl.line)
  console.log('Readline paused.');
});

This is a screenshot from the debugger:
image

And so \n is used in the next part of the code.
Am I wrong in some way?

@bnoordhuis
Copy link
Member

I don't have a Windows machine at hand but I can't reproduce on Linux or macOS. Maybe it's Windows-specific or maybe it's something your debugger does?

I suppose it could be related to the fact Windows uses \r\n instead of \n as line separators.

Something you can test is whether console.log(rl.line.includes('\\\n')) prints true or false in your program.

@albertopasqualetto
Copy link
Author

albertopasqualetto commented Dec 28, 2022

Maybe you meant rl.line.includes('\\n')? This prints true.

Both rl.line.includes('\\\n') and `rl.line.includes('\n')' print false.

The test is "test\ntest" input and then Ctrl-C.

@StefanStojanovic
Copy link
Contributor

What I think is making confusion here is the backslash usage, because it's an escape character. With that in mind, when in some string you have \n that is actually a new line, having \\n results in \n (which is the case we have here), and having \\\n results in a backslash (\) followed by a new line.

I ran the following code on both Windows and Linux in VS Code terminal with input test\ntest:

const readline = require("node:readline");
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on("pause", () => {
  console.log();
  console.log("Line: " + rl.line);
  console.log("backslash N:", rl.line.includes("\n"));
  console.log("backslash backslash N:", rl.line.includes("\\n"));
  console.log("backslash backslash backslash N:", rl.line.includes("\\\n"));
  console.log("Readline paused.");
});

and the outputs were identical:

Line: test\ntest
backslash N: false
backslash backslash N: true
backslash backslash backslash N: false
Readline paused.

On both OSs in the debugger, I saw rs.line having the value of "test\\ntest" but as I mentioned previously that is because of the backslash escape sequence usage.

@albertopasqualetto
Copy link
Author

Thanks for the tests Stefan.

What I think is making confusion here is the backslash usage, because it's an escape character.

Exactly.

With that in mind, when in some string you have \n that is actually a new line, having \\n results in \n (which is the case we have here)

Yes, it prints "\n" (which could be ok for printing, but not always for using line in code) because it is escaped by the library.

But Ben said that there should not be escaping:

I'm fairly sure no escaping takes place inside the readline module

Now I think that what is missing is if readline module intent is to escape or not.

@V7lanw
Copy link

V7lanw commented Mar 2, 2023

Hi @StefanStojanovic , I copy your code in my Win 10 and the result is

image

The first attempt was "test\ntest" + Enter + "qwerty" + Backspace * 6 + Ctrl + c, and the second attempt was "test\ntest" + Ctrl + c.

I am noob here, and my case is using Inquirer package to build a CLI tool for my self. I would like to write a one-line string with \n but it should be read and processed into multiple lines. (I know it sounds weird, but I would like to implement a chatbox just like slack in CLI). I don't know how to block Enter or enable Shift + Enter as adding a new line.

image

Or another way to implement that is invoking vim editor using other node functions, and read what I wrote in that temporary vim txt file? I just have this idea, and I guess this way is too complicated for me now.

@V7lanw
Copy link

V7lanw commented Mar 2, 2023

Or another way to implement that is invoking vim editor using other node functions, and read what I wrote in that temporary vim txt file? I just have this idea, and I guess this way is too complicated for me now.

Sorry, I guess I found the answer to this.

But I am still curious about the code here, if I press Backspace, things are different, and console.log("Line: " + rl.line); cannot give me what I input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants