Skip to content

Commit c1cb472

Browse files
authored
Merge branch 'main' into disable-sockepair-auth-on-wasi
2 parents e71d5a7 + d22922c commit c1cb472

File tree

10 files changed

+79
-8
lines changed

10 files changed

+79
-8
lines changed

Doc/library/argparse.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1970,7 +1970,7 @@ FileType objects
19701970
run and then use the :keyword:`with`-statement to manage the files.
19711971

19721972
.. versionchanged:: 3.4
1973-
Added the *encodings* and *errors* parameters.
1973+
Added the *encoding* and *errors* parameters.
19741974

19751975
.. deprecated:: 3.14
19761976

Include/internal/pycore_dict.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ _PyDict_NotifyEvent(PyDict_WatchEvent event,
292292
PyObject *value)
293293
{
294294
assert(Py_REFCNT((PyObject*)mp) > 0);
295-
int watcher_bits = FT_ATOMIC_LOAD_UINT64_RELAXED(mp->_ma_watcher_tag) & DICT_WATCHER_MASK;
295+
int watcher_bits = FT_ATOMIC_LOAD_UINT64_ACQUIRE(mp->_ma_watcher_tag) & DICT_WATCHER_MASK;
296296
if (watcher_bits) {
297297
RARE_EVENT_STAT_INC(watched_dict_modification);
298298
_PyDict_SendEvent(watcher_bits, event, mp, key, value);

Include/internal/pycore_pyatomic_ft_wrappers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ extern "C" {
4949
_Py_atomic_load_uint16_relaxed(&value)
5050
#define FT_ATOMIC_LOAD_UINT32_RELAXED(value) \
5151
_Py_atomic_load_uint32_relaxed(&value)
52+
#define FT_ATOMIC_LOAD_UINT64_ACQUIRE(value) \
53+
_Py_atomic_load_uint64_acquire(&value)
5254
#define FT_ATOMIC_LOAD_UINT64_RELAXED(value) \
5355
_Py_atomic_load_uint64_relaxed(&value)
5456
#define FT_ATOMIC_LOAD_ULONG_RELAXED(value) \
@@ -154,6 +156,7 @@ extern "C" {
154156
#define FT_ATOMIC_LOAD_UINT8_RELAXED(value) value
155157
#define FT_ATOMIC_LOAD_UINT16_RELAXED(value) value
156158
#define FT_ATOMIC_LOAD_UINT32_RELAXED(value) value
159+
#define FT_ATOMIC_LOAD_UINT64_ACQUIRE(value) value
157160
#define FT_ATOMIC_LOAD_UINT64_RELAXED(value) value
158161
#define FT_ATOMIC_LOAD_ULONG_RELAXED(value) value
159162
#define FT_ATOMIC_STORE_PTR_RELAXED(value, new_value) value = new_value

Lib/statistics.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@
145145
from collections import Counter, namedtuple, defaultdict
146146

147147
_SQRT2 = sqrt(2.0)
148+
_SQRT2PI = sqrt(tau)
148149
_random = random
149150

150151
## Exceptions ##############################################################
@@ -1257,11 +1258,11 @@ def samples(self, n, *, seed=None):
12571258

12581259
def pdf(self, x):
12591260
"Probability density function. P(x <= X < x+dx) / dx"
1260-
variance = self._sigma * self._sigma
1261-
if not variance:
1261+
sigma = self._sigma
1262+
if not sigma:
12621263
raise StatisticsError('pdf() not defined when sigma is zero')
1263-
diff = x - self._mu
1264-
return exp(diff * diff / (-2.0 * variance)) / sqrt(tau * variance)
1264+
z = (x - self._mu) / sigma
1265+
return exp(-0.5 * z * z) / (_SQRT2PI * sigma)
12651266

12661267
def cdf(self, x):
12671268
"Cumulative distribution function. P(X <= x)"

Lib/test/test_capi/test_opt.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2845,6 +2845,35 @@ def testfunc(n):
28452845
uops = get_opnames(ex)
28462846
self.assertNotIn("_CHECK_IS_NOT_PY_CALLABLE", uops)
28472847

2848+
def test_check_is_not_py_callable_ex(self):
2849+
def testfunc(n):
2850+
total = 0
2851+
xs = (1, 2, 3)
2852+
args = (xs,)
2853+
for _ in range(n):
2854+
total += len(*args)
2855+
return total
2856+
2857+
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
2858+
self.assertEqual(res, 3 * TIER2_THRESHOLD)
2859+
self.assertIsNotNone(ex)
2860+
uops = get_opnames(ex)
2861+
self.assertNotIn("_CHECK_IS_NOT_PY_CALLABLE_EX", uops)
2862+
2863+
def test_check_is_not_py_callable_kw(self):
2864+
def testfunc(n):
2865+
total = 0
2866+
xs = (3, 1, 2)
2867+
for _ in range(n):
2868+
total += sorted(xs, reverse=False)[0]
2869+
return total
2870+
2871+
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
2872+
self.assertEqual(res, TIER2_THRESHOLD)
2873+
self.assertIsNotNone(ex)
2874+
uops = get_opnames(ex)
2875+
self.assertNotIn("_CHECK_IS_NOT_PY_CALLABLE_KW", uops)
2876+
28482877
def test_call_len_string(self):
28492878
def testfunc(n):
28502879
for _ in range(n):

Lib/test/test_webbrowser.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ def test_open_bad_new_parameter(self):
119119
arguments=[URL],
120120
kw=dict(new=999))
121121

122+
def test_reject_action_dash_prefixes(self):
123+
browser = self.browser_class(name=CMD_NAME)
124+
with self.assertRaises(ValueError):
125+
browser.open('%action--incognito')
126+
# new=1: action is "--new-window", so "%action" itself expands to
127+
# a dash-prefixed flag even with no dash in the original URL.
128+
with self.assertRaises(ValueError):
129+
browser.open('%action', new=1)
130+
122131

123132
class EdgeCommandTest(CommandTestMixin, unittest.TestCase):
124133

Lib/webbrowser.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,6 @@ def _invoke(self, args, remote, autoraise, url=None):
274274

275275
def open(self, url, new=0, autoraise=True):
276276
sys.audit("webbrowser.open", url)
277-
self._check_url(url)
278277
if new == 0:
279278
action = self.remote_action
280279
elif new == 1:
@@ -288,7 +287,9 @@ def open(self, url, new=0, autoraise=True):
288287
raise Error("Bad 'new' parameter to open(); "
289288
f"expected 0, 1, or 2, got {new}")
290289

291-
args = [arg.replace("%s", url).replace("%action", action)
290+
self._check_url(url.replace("%action", action))
291+
292+
args = [arg.replace("%action", action).replace("%s", url)
292293
for arg in self.remote_args]
293294
args = [arg for arg in args if arg]
294295
success = self._invoke(args, True, autoraise, url)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
A bypass in :mod:`webbrowser` allowed URLs prefixed with ``%action`` to pass
2+
the dash-prefix safety check.

Python/optimizer_bytecodes.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,20 @@ dummy_func(void) {
13201320
}
13211321
}
13221322

1323+
op(_CHECK_IS_NOT_PY_CALLABLE_EX, (func_st, unused, unused, unused -- func_st, unused, unused, unused)) {
1324+
PyTypeObject *type = sym_get_type(func_st);
1325+
if (type && type != &PyFunction_Type) {
1326+
ADD_OP(_NOP, 0, 0);
1327+
}
1328+
}
1329+
1330+
op(_CHECK_IS_NOT_PY_CALLABLE_KW, (callable, unused, unused[oparg], unused -- callable, unused, unused[oparg], unused)) {
1331+
PyTypeObject *type = sym_get_type(callable);
1332+
if (type && type != &PyFunction_Type && type != &PyMethod_Type) {
1333+
ADD_OP(_NOP, 0, 0);
1334+
}
1335+
}
1336+
13231337
op(_PUSH_FRAME, (new_frame -- )) {
13241338
SYNC_SP();
13251339
if (!CURRENT_FRAME_IS_INIT_SHIM()) {

Python/optimizer_cases.c.h

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)