Skip to content

Commit 5981c72

Browse files
authoredMar 29, 2024··
Change newline when setting context.os to "windows" (#2330)
* Change newline when setting `context.os` Windows uses `b'\r\n'` for newlines while unix uses `b'\n'`. Change the expected newline to `b'\r\n'` when setting `context.os = "windows"` automatically for convenience. * Update CHANGELOG * Fix other tests setting os
1 parent cb54085 commit 5981c72

File tree

2 files changed

+70
-9
lines changed

2 files changed

+70
-9
lines changed
 

‎CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,14 @@ The table below shows which release corresponds to each branch, and what date th
7676
- [#2374][2374] libcdb.unstrip_libc: debug symbols are fetched only if not present
7777
- [#2327][2327] Add basic support to debug processes on Windows
7878
- [#2322][2322] Add basic RISCV64 shellcraft support
79+
- [#2330][2330] Change `context.newline` when setting `context.os` to `"windows"`
7980

8081
[2360]: https://github.com/Gallopsled/pwntools/pull/2360
8182
[2356]: https://github.com/Gallopsled/pwntools/pull/2356
8283
[2374]: https://github.com/Gallopsled/pwntools/pull/2374
8384
[2327]: https://github.com/Gallopsled/pwntools/pull/2327
8485
[2322]: https://github.com/Gallopsled/pwntools/pull/2322
86+
[2330]: https://github.com/Gallopsled/pwntools/pull/2330
8587

8688
## 4.13.0 (`beta`)
8789

‎pwnlib/context/__init__.py

+68-9
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ class ContextType(object):
302302
>>> context.os == 'linux'
303303
True
304304
>>> context.arch = 'arm'
305-
>>> vars(context) == {'arch': 'arm', 'bits': 32, 'endian': 'little', 'os': 'linux'}
305+
>>> vars(context) == {'arch': 'arm', 'bits': 32, 'endian': 'little', 'os': 'linux', 'newline': b'\n'}
306306
True
307307
>>> context.endian
308308
'little'
@@ -376,8 +376,19 @@ class ContextType(object):
376376
'timeout': Timeout.maximum,
377377
}
378378

379-
#: Valid values for :meth:`pwnlib.context.ContextType.os`
380-
oses = sorted(('linux','freebsd','windows','cgc','android','baremetal','darwin'))
379+
unix_like = {'newline': b'\n'}
380+
windows_like = {'newline': b'\r\n'}
381+
382+
#: Keys are valid values for :meth:`pwnlib.context.ContextType.os`
383+
oses = _longest({
384+
'linux': unix_like,
385+
'freebsd': unix_like,
386+
'windows': windows_like,
387+
'cgc': unix_like,
388+
'android': unix_like,
389+
'baremetal': unix_like,
390+
'darwin': unix_like,
391+
})
381392

382393
big_32 = {'endian': 'big', 'bits': 32}
383394
big_64 = {'endian': 'big', 'bits': 64}
@@ -446,14 +457,14 @@ def __init__(self, **kwargs):
446457

447458

448459
def copy(self):
449-
"""copy() -> dict
460+
r"""copy() -> dict
450461
Returns a copy of the current context as a dictionary.
451462
452463
Examples:
453464
454465
>>> context.clear()
455466
>>> context.os = 'linux'
456-
>>> vars(context) == {'os': 'linux'}
467+
>>> vars(context) == {'os': 'linux', 'newline': b'\n'}
457468
True
458469
"""
459470
return self._tls.copy()
@@ -1104,25 +1115,73 @@ def mask(self):
11041115

11051116
@_validator
11061117
def os(self, os):
1107-
"""
1118+
r"""
11081119
Operating system of the target machine.
11091120
11101121
The default value is ``linux``.
11111122
11121123
Allowed values are listed in :attr:`pwnlib.context.ContextType.oses`.
11131124
1125+
Side Effects:
1126+
1127+
If an os is specified some attributes will be set on the context
1128+
if a user has not already set a value.
1129+
1130+
The following property may be modified:
1131+
1132+
- :attr:`newline`
1133+
1134+
Raises:
1135+
AttributeError: An invalid os was specified
1136+
11141137
Examples:
11151138
1116-
>>> context.os = 'linux'
1139+
>>> context.clear()
1140+
>>> context.os == 'linux' # Default os
1141+
True
1142+
1143+
>>> context.os = 'freebsd'
1144+
>>> context.os == 'freebsd'
1145+
True
1146+
11171147
>>> context.os = 'foobar' #doctest: +ELLIPSIS
11181148
Traceback (most recent call last):
11191149
...
11201150
AttributeError: os must be one of ['android', 'baremetal', 'cgc', 'freebsd', 'linux', 'windows']
1151+
1152+
>>> context.clear()
1153+
>>> context.newline == b'\n' # Default value
1154+
True
1155+
>>> context.os = 'windows'
1156+
>>> context.newline == b'\r\n' # New value
1157+
True
1158+
1159+
Note that expressly setting :attr:`newline` means that we use
1160+
that value instead of the default
1161+
1162+
>>> context.clear()
1163+
>>> context.newline = b'\n'
1164+
>>> context.os = 'windows'
1165+
>>> context.newline == b'\n'
1166+
True
1167+
1168+
Setting the os can override the default for :attr:`newline`
1169+
1170+
>>> context.clear()
1171+
>>> context.os = 'windows'
1172+
>>> vars(context) == {'os': 'windows', 'newline': b'\r\n'}
1173+
True
11211174
"""
11221175
os = os.lower()
11231176

1124-
if os not in self.oses:
1125-
raise AttributeError("os must be one of %r" % self.oses)
1177+
try:
1178+
defaults = self.oses[os]
1179+
except KeyError:
1180+
raise AttributeError("os must be one of %r" % sorted(self.oses))
1181+
1182+
for k,v in defaults.items():
1183+
if k not in self._tls:
1184+
self._tls[k] = v
11261185

11271186
return os
11281187

0 commit comments

Comments
 (0)
Please sign in to comment.