• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Gallopsled / pwntools / 1

18 May 2023 08:32PM UTC coverage: 19.336% (-54.2%) from 73.494%
1

push

github

web-flow
Handle `context.newline` correctly in `tube.interactive()` (#2129)

* Handle `context.newline` correctly in `tube.interactive()`

The `context.newline` or `self.newline` variable isn't obeyed when typing in interactive mode. It is used when sending and receiving lines through `tube.sendline` though, causing a mismatch.

The receiving end of the `tube.interactive()` already has handling of newlines, but the sending side does not.

Example:
```python
from pwn import *
io = process('cat')
io.newline = b'\r\n'
io.sendline(b'auto')
io.interactive()
```

```
$ python testinteractive.py DEBUG
[x] Starting local process '/usr/bin/cat' argv=[b'cat']
[+] Starting local process '/usr/bin/cat' argv=[b'cat'] : pid 19060
[DEBUG] Sent 0x6 bytes:
    b'auto\r\n'
[*] Switching to interactive mode
[DEBUG] Received 0x6 bytes:
    b'auto\r\n'
auto
$ test
[DEBUG] Sent 0x5 bytes:
    b'test\n'
[DEBUG] Received 0x5 bytes:
    b'test\n'
test
```

The expected outcome would be to send `b'test\r\n'.

The same problem arises in non-term mode (`PWNLIB_NOTERM=1`), where stdin is read in binary mode causing the OS line seperators to come through. Correctly replacing them with the `context.newline` setting allows to use the interactive input on windows hosts as well, without constantly sending `\r\n`.

* Update CHANGELOG.md

* Only replace newlines in TTYs

Don't mess with the line endings when piping data through.

* Always send bytes immediately on receive

Only replace newlines in a tty if NOTERM wasn't explicitly set or
the `newline` setting was set.

* Don't return a newline after term.readline lines

The builtin `input()` doesn't include the newline.

* Remove bogous newline from CHANGELOG

189 of 5940 branches covered (3.18%)

1 of 20 new or added lines in 2 files covered. (5.0%)

9283 existing lines in 112 files now uncovered.

3286 of 16994 relevant lines covered (19.34%)

0.39 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/pwnlib/commandline/unhex.py
1
#!/usr/bin/env python2
UNCOV
2
from __future__ import absolute_import
×
UNCOV
3
from __future__ import division
×
4

UNCOV
5
import argparse
×
UNCOV
6
import sys
×
UNCOV
7
from string import whitespace
×
8

UNCOV
9
from pwnlib.commandline import common
×
UNCOV
10
from pwnlib.util.fiddling import unhex
×
11

UNCOV
12
parser = common.parser_commands.add_parser(
×
13
    'unhex',
14
    help = 'Decodes hex-encoded data provided on the command line or via stdin.',
15
    description = 'Decodes hex-encoded data provided on the command line or via stdin.'
16
)
17

UNCOV
18
parser.add_argument('hex', nargs='*',
×
19
    help='Hex bytes to decode')
20

UNCOV
21
def main(args):
×
UNCOV
22
    try:
×
UNCOV
23
        o = getattr(sys.stdout, 'buffer', sys.stdout)
×
UNCOV
24
        if not args.hex:
×
25
            s = getattr(sys.stdin, 'buffer', sys.stdin).read().translate(None, whitespace.encode('ascii'))
×
26
            o.write(unhex(s))
×
27
        else:
UNCOV
28
            o.write(unhex(''.join(args.hex)))
×
29
    except TypeError as e:
×
30
        sys.stderr.write(str(e) + '\n')
×
31
        raise
×
32

UNCOV
33
if __name__ == '__main__':
×
UNCOV
34
    common.main(__file__)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc