我能否确定终端是否解释 C1 控制代码?
ISO/IEC 2022 定义了C0 和 C1 控制代码。 C0 集是 ASCII、ISO-8859-1 和 UTF-8 中 0x00
和 0x1f
之间熟悉的代码(例如 ESC、< kbd>CR,LF)。
一些 VT100 终端仿真器(例如 screen(1)
、PuTTY)也支持 C1 集。这些是 0x80
和 0x9f
之间的值(例如,0x84
将光标向下移动一行)。
我正在显示用户提供的输入。我不希望用户输入能够改变终端状态(例如移动光标)。我目前正在过滤掉C0集中的字符编码;但是,如果终端将它们解释为控制代码,我也想有条件地过滤掉 C1 集。
有没有办法从像 termcap
这样的数据库获取这些信息?
ISO/IEC 2022 defines the C0 and C1 control codes. The C0 set are the familiar codes between 0x00
and 0x1f
in ASCII, ISO-8859-1 and UTF-8 (eg. ESC, CR, LF).
Some VT100 terminal emulators (eg. screen(1)
, PuTTY) support the C1 set, too. These are the values between 0x80
and 0x9f
(so, for example, 0x84
moves the cursor down a line).
I am displaying user-supplied input. I do not wish the user input to be able to alter the terminal state (eg. move the cursor). I am currently filtering out the character codes in the C0 set; however I would like to conditionally filter out the C1 set too, if terminal will interpret them as control codes.
Is there a way of getting this information from a database like termcap
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我能想到的唯一方法是使用 C1 请求并测试返回值:
以上是:
ESR 维护的 terminfo/termcap (link) 在用户字符串 7 和 9(user7/u7、user9/u9)中有几个这样的请求:
示例:
当然,如果您只想防止显示损坏,可以使用
less
方法,让用户在显示/不显示控制字符之间切换(中的 -r 和 -R 选项)少
)。另外,如果您知道输出字符集,则 ISO-8859 字符集具有为控制代码保留的 C1 范围(因此它们在该范围内没有可打印字符)。The only way to do it that I can think of is using C1 requests and testing the return value:
The above ones are:
The terminfo/termcap that ESR maintains (link) has a couple of these requests in user strings 7 and 9 (user7/u7, user9/u9):
Example:
Of course, if you only want to prevent display corruption, you can use
less
approach, and let the user switch between displaying/not displaying control characters (-r and -R options inless
). Also, if you know your output charset, ISO-8859 charsets have the C1 range reserved for control codes (so they have no printable chars in that range).实际上,PuTTY 似乎不支持 C1 控件。
测试此功能的常用方法是使用 vttest,它提供了用于更改输入的菜单条目- 和输出- 分别使用8 位控制。 PuTTY 无法对每个菜单项进行健全性检查,如果禁用该检查,结果将确认 PuTTY 不遵守这些控件。
Actually, PuTTY does not appear to support C1 controls.
The usual way of testing this feature is with vttest, which provides menu entries for changing the input- and output- separately to use 8-bit controls. PuTTY fails the sanity-check for each of those menu entries, and if the check is disabled, the result confirms that PuTTY does not honor those controls.
我认为没有一种直接的方法来查询终端是否支持它们。您可以尝试令人讨厌的黑客解决方法(例如打印它们然后查询光标位置),但我真的不建议这样做。
我认为你可以无条件地过滤掉这些C1代码。无论如何,Unicode 将 U+0080.. U+009F 范围声明为控制字符,我认为您不应该将它们用于任何不同的用途。
(注意:您使用了
0x84
示例来表示光标向下。实际上,U+0084
以终端使用的任何编码进行编码,例如0xC2 0x84
对于 UTF-8。)I don't think there's a straightforward way to query whether the terminal supports them. You can try nasty hacky workarounds (like print them and then query the cursor position) but I really don't recommend anything along these lines.
I think you could just filter out these C1 codes unconditionally. Unicode declares the U+0080.. U+009F range as control characters anyway, I don't think you should ever use them for anything different.
(Note: you used the example
0x84
for cursor down. It's in factU+0084
encoded in whichever encoding the terminal uses, e.g.0xC2 0x84
for UTF-8.)100% 自动完成这件事充其量也具有挑战性。许多(如果不是大多数)Unix 接口都是智能的(xterms 等),但您实际上不知道是否连接到 ASR33 或运行 MSDOS 的 PC。
您可以尝试一些终端询问转义序列和超时(如果没有回复)。但随后您可能不得不回退并询问用户他们正在使用哪种终端。
Doing it 100% automatically is challenging at best. Many, if not most, Unix interfaces are smart (xterms and whatnot), but you don't actually know if connected to an ASR33 or a PC running MSDOS.
You could try some of the terminal interrogation escape sequences and timeout if there is no reply. But then you might have to fall back and maybe ask the user what kind of terminal they are using.