[3.5] bpo-29854: Fix segfault in call_readline() (GH-728) · python/cpython@68c3724 (original) (raw)

`@@ -9,7 +9,7 @@

`

9

9

`import sys

`

10

10

`import tempfile

`

11

11

`import unittest

`

12

``

`-

from test.support import import_module, unlink, TESTFN

`

``

12

`+

from test.support import import_module, unlink, temp_dir, TESTFN

`

13

13

`from test.support.script_helper import assert_python_ok

`

14

14

``

15

15

`# Skip tests if there is no readline module

`

`@@ -195,13 +195,57 @@ def display(substitution, matches, longest_match_length):

`

195

195

`self.assertIn(b"result " + expected + b"\r\n", output)

`

196

196

`self.assertIn(b"history " + expected + b"\r\n", output)

`

197

197

``

``

198

`+

We have 2 reasons to skip this test:

`

``

199

`+

- readline: history size was added in 6.0

`

``

200

`+

See https://cnswww.cns.cwru.edu/php/chet/readline/CHANGES

`

``

201

`+

- editline: history size is broken on OS X 10.11.6.

`

``

202

`+

Newer versions were not tested yet.

`

``

203

`+

@unittest.skipIf(readline._READLINE_VERSION < 0x600,

`

``

204

`+

"this readline version does not support history-size")

`

``

205

`+

@unittest.skipIf(is_editline,

`

``

206

`+

"editline history size configuration is broken")

`

``

207

`+

def test_history_size(self):

`

``

208

`+

history_size = 10

`

``

209

`+

with temp_dir() as test_dir:

`

``

210

`+

inputrc = os.path.join(test_dir, "inputrc")

`

``

211

`+

with open(inputrc, "wb") as f:

`

``

212

`+

f.write(b"set history-size %d\n" % history_size)

`

``

213

+

``

214

`+

history_file = os.path.join(test_dir, "history")

`

``

215

`+

with open(history_file, "wb") as f:

`

``

216

`+

history_size * 2 items crashes readline

`

``

217

`+

data = b"".join(b"item %d\n" % i

`

``

218

`+

for i in range(history_size * 2))

`

``

219

`+

f.write(data)

`

``

220

+

``

221

`+

script = """

`

``

222

`+

import os

`

``

223

`+

import readline

`

``

224

+

``

225

`+

history_file = os.environ["HISTORY_FILE"]

`

``

226

`+

readline.read_history_file(history_file)

`

``

227

`+

input()

`

``

228

`+

readline.write_history_file(history_file)

`

``

229

`+

"""

`

``

230

+

``

231

`+

env = dict(os.environ)

`

``

232

`+

env["INPUTRC"] = inputrc

`

``

233

`+

env["HISTORY_FILE"] = history_file

`

``

234

+

``

235

`+

run_pty(script, input=b"last input\r", env=env)

`

``

236

+

``

237

`+

with open(history_file, "rb") as f:

`

``

238

`+

lines = f.readlines()

`

``

239

`+

self.assertEqual(len(lines), history_size)

`

``

240

`+

self.assertEqual(lines[-1].strip(), b"last input")

`

``

241

+

198

242

``

199

``

`-

def run_pty(script, input=b"dummy input\r"):

`

``

243

`+

def run_pty(script, input=b"dummy input\r", env=None):

`

200

244

`pty = import_module('pty')

`

201

245

`output = bytearray()

`

202

246

` [master, slave] = pty.openpty()

`

203

247

`args = (sys.executable, '-c', script)

`

204

``

`-

proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave)

`

``

248

`+

proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave, env=env)

`

205

249

`os.close(slave)

`

206

250

`with ExitStack() as cleanup:

`

207

251

`cleanup.enter_context(proc)

`