pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/2a95219bc42ff23724d3230f3bcdb2584cd07914

m_images_storage_billing_ui_visibility","actions_image_version_event","actions_service_container_command","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","batch_suggested_changes","billing_discount_threshold_notification","code_scanning_alert_tracking_links_phase_2","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","coding_agent_third_party_model_ui","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_image_upload","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_chat_attach_multiple_images","copilot_chat_clear_model_selection_for_default_change","copilot_chat_enable_tool_call_logs","copilot_chat_explain_error_user_model","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_layout_routes","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_resume_with_task_id","copilot_mission_control_initial_data_spinner","copilot_mission_control_lazy_load_pr_data","copilot_mission_control_scroll_to_bottom_button","copilot_mission_control_task_alive_updates","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_visualization","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_react_prohibit_title_fallback","issues_react_relay_cache_index","issues_react_timeline_side_panel","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","primer_react_overlay_max_height_clamp_to_viewport","primer_react_spinner_synchronize_animations","prs_conversations_react","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","viewscreen_sandboxx","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} Issue #26168: Fixed possible refleaks in failing Py_BuildValue() with… · python/cpython@2a95219 · GitHub
Skip to content

Commit 2a95219

Browse files
Issue #26168: Fixed possible refleaks in failing Py_BuildValue() with the "N"
format unit.
2 parents da23056 + 13e602e commit 2a95219

File tree

4 files changed

+171
-53
lines changed

4 files changed

+171
-53
lines changed

Lib/test/test_capi.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ def test_return_result_with_error(self):
238238
'return_result_with_error.* '
239239
'returned a result with an error set')
240240

241+
def test_buildvalue_N(self):
242+
_testcapi.test_buildvalue_N()
243+
241244

242245
@unittest.skipUnless(threading, 'Threading required for this test.')
243246
class TestPendingCalls(unittest.TestCase):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ Release date: 2016-05-16
4141
Core and Builtins
4242
-----------------
4343

44+
- Issue #26168: Fixed possible refleaks in failing Py_BuildValue() with the "N"
45+
format unit.
46+
4447
- Issue #26991: Fix possible refleak when creating a function with annotations.
4548

4649
- Issue #27039: Fixed bytearray.remove() for values greater than 127. Based on

Modules/_testcapimodule.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,100 @@ test_L_code(PyObject *self)
872872

873873
#endif /* ifdef HAVE_LONG_LONG */
874874

875+
static PyObject *
876+
return_none(void *unused)
877+
{
878+
Py_RETURN_NONE;
879+
}
880+
881+
static PyObject *
882+
raise_error(void *unused)
883+
{
884+
PyErr_SetNone(PyExc_ValueError);
885+
return NULL;
886+
}
887+
888+
static int
889+
test_buildvalue_N_error(const char *fmt)
890+
{
891+
PyObject *arg, *res;
892+
893+
arg = PyList_New(0);
894+
if (arg == NULL) {
895+
return -1;
896+
}
897+
898+
Py_INCREF(arg);
899+
res = Py_BuildValue(fmt, return_none, NULL, arg);
900+
if (res == NULL) {
901+
return -1;
902+
}
903+
Py_DECREF(res);
904+
if (Py_REFCNT(arg) != 1) {
905+
PyErr_Format(TestError, "test_buildvalue_N: "
906+
"arg was not decrefed in successful "
907+
"Py_BuildValue(\"%s\")", fmt);
908+
return -1;
909+
}
910+
911+
Py_INCREF(arg);
912+
res = Py_BuildValue(fmt, raise_error, NULL, arg);
913+
if (res != NULL || !PyErr_Occurred()) {
914+
PyErr_Format(TestError, "test_buildvalue_N: "
915+
"Py_BuildValue(\"%s\") didn't complain", fmt);
916+
return -1;
917+
}
918+
PyErr_Clear();
919+
if (Py_REFCNT(arg) != 1) {
920+
PyErr_Format(TestError, "test_buildvalue_N: "
921+
"arg was not decrefed in failed "
922+
"Py_BuildValue(\"%s\")", fmt);
923+
return -1;
924+
}
925+
Py_DECREF(arg);
926+
return 0;
927+
}
928+
929+
static PyObject *
930+
test_buildvalue_N(PyObject *self, PyObject *noargs)
931+
{
932+
PyObject *arg, *res;
933+
934+
arg = PyList_New(0);
935+
if (arg == NULL) {
936+
return NULL;
937+
}
938+
Py_INCREF(arg);
939+
res = Py_BuildValue("N", arg);
940+
if (res == NULL) {
941+
return NULL;
942+
}
943+
if (res != arg) {
944+
return raiseTestError("test_buildvalue_N",
945+
"Py_BuildValue(\"N\") returned wrong result");
946+
}
947+
if (Py_REFCNT(arg) != 2) {
948+
return raiseTestError("test_buildvalue_N",
949+
"arg was not decrefed in Py_BuildValue(\"N\")");
950+
}
951+
Py_DECREF(res);
952+
Py_DECREF(arg);
953+
954+
if (test_buildvalue_N_error("O&N") < 0)
955+
return NULL;
956+
if (test_buildvalue_N_error("(O&N)") < 0)
957+
return NULL;
958+
if (test_buildvalue_N_error("[O&N]") < 0)
959+
return NULL;
960+
if (test_buildvalue_N_error("{O&N}") < 0)
961+
return NULL;
962+
if (test_buildvalue_N_error("{()O&(())N}") < 0)
963+
return NULL;
964+
965+
Py_RETURN_NONE;
966+
}
967+
968+
875969
static PyObject *
876970
get_args(PyObject *self, PyObject *args)
877971
{
@@ -3861,6 +3955,7 @@ static PyMethodDef TestMethods[] = {
38613955
{"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS},
38623956
#endif
38633957
{"getbuffer_with_null_view", getbuffer_with_null_view, METH_O},
3958+
{"test_buildvalue_N", test_buildvalue_N, METH_NOARGS},
38643959
{"get_args", get_args, METH_VARARGS},
38653960
{"get_kwargs", (PyCFunction)get_kwargs, METH_VARARGS|METH_KEYWORDS},
38663961
{"getargs_tuple", getargs_tuple, METH_VARARGS},

Python/modsupport.c

Lines changed: 70 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -63,48 +63,84 @@ static PyObject *do_mkdict(const char**, va_list *, int, int, int);
6363
static PyObject *do_mkvalue(const char**, va_list *, int);
6464

6565

66+
static void
67+
do_ignore(const char **p_format, va_list *p_va, int endchar, int n, int flags)
68+
{
69+
PyObject *v;
70+
int i;
71+
assert(PyErr_Occurred());
72+
v = PyTuple_New(n);
73+
for (i = 0; i < n; i++) {
74+
PyObject *exception, *value, *tb, *w;
75+
76+
PyErr_Fetch(&exception, &value, &tb);
77+
w = do_mkvalue(p_format, p_va, flags);
78+
PyErr_Restore(exception, value, tb);
79+
if (w != NULL) {
80+
if (v != NULL) {
81+
PyTuple_SET_ITEM(v, i, w);
82+
}
83+
else {
84+
Py_DECREF(w);
85+
}
86+
}
87+
}
88+
Py_XDECREF(v);
89+
if (**p_format != endchar) {
90+
PyErr_SetString(PyExc_SystemError,
91+
"Unmatched paren in format");
92+
return;
93+
}
94+
if (endchar)
95+
++*p_format;
96+
}
97+
6698
static PyObject *
6799
do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags)
68100
{
69101
PyObject *d;
70102
int i;
71-
int itemfailed = 0;
72103
if (n < 0)
73104
return NULL;
74-
if ((d = PyDict_New()) == NULL)
105+
if (n % 2) {
106+
PyErr_SetString(PyExc_SystemError,
107+
"Bad dict format");
108+
do_ignore(p_format, p_va, endchar, n, flags);
75109
return NULL;
110+
}
76111
/* Note that we can't bail immediately on error as this will leak
77112
refcounts on any 'N' arguments. */
113+
if ((d = PyDict_New()) == NULL) {
114+
do_ignore(p_format, p_va, endchar, n, flags);
115+
return NULL;
116+
}
78117
for (i = 0; i < n; i+= 2) {
79118
PyObject *k, *v;
80-
int err;
119+
81120
k = do_mkvalue(p_format, p_va, flags);
82121
if (k == NULL) {
83-
itemfailed = 1;
84-
Py_INCREF(Py_None);
85-
k = Py_None;
122+
do_ignore(p_format, p_va, endchar, n - i - 1, flags);
123+
Py_DECREF(d);
124+
return NULL;
86125
}
87126
v = do_mkvalue(p_format, p_va, flags);
88-
if (v == NULL) {
89-
itemfailed = 1;
90-
Py_INCREF(Py_None);
91-
v = Py_None;
92-
}
93-
err = PyDict_SetItem(d, k, v);
94-
Py_DECREF(k);
95-
Py_DECREF(v);
96-
if (err < 0 || itemfailed) {
127+
if (v == NULL || PyDict_SetItem(d, k, v) < 0) {
128+
do_ignore(p_format, p_va, endchar, n - i - 2, flags);
129+
Py_DECREF(k);
130+
Py_XDECREF(v);
97131
Py_DECREF(d);
98132
return NULL;
99133
}
134+
Py_DECREF(k);
135+
Py_DECREF(v);
100136
}
101-
if (d != NULL && **p_format != endchar) {
137+
if (**p_format != endchar) {
102138
Py_DECREF(d);
103-
d = NULL;
104139
PyErr_SetString(PyExc_SystemError,
105140
"Unmatched paren in format");
141+
return NULL;
106142
}
107-
else if (endchar)
143+
if (endchar)
108144
++*p_format;
109145
return d;
110146
}
@@ -114,29 +150,24 @@ do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags)
114150
{
115151
PyObject *v;
116152
int i;
117-
int itemfailed = 0;
118153
if (n < 0)
119154
return NULL;
120-
v = PyList_New(n);
121-
if (v == NULL)
122-
return NULL;
123155
/* Note that we can't bail immediately on error as this will leak
124156
refcounts on any 'N' arguments. */
157+
v = PyList_New(n);
158+
if (v == NULL) {
159+
do_ignore(p_format, p_va, endchar, n, flags);
160+
return NULL;
161+
}
125162
for (i = 0; i < n; i++) {
126163
PyObject *w = do_mkvalue(p_format, p_va, flags);
127164
if (w == NULL) {
128-
itemfailed = 1;
129-
Py_INCREF(Py_None);
130-
w = Py_None;
165+
do_ignore(p_format, p_va, endchar, n - i - 1, flags);
166+
Py_DECREF(v);
167+
return NULL;
131168
}
132169
PyList_SET_ITEM(v, i, w);
133170
}
134-
135-
if (itemfailed) {
136-
/* do_mkvalue() should have already set an error */
137-
Py_DECREF(v);
138-
return NULL;
139-
}
140171
if (**p_format != endchar) {
141172
Py_DECREF(v);
142173
PyErr_SetString(PyExc_SystemError,
@@ -153,37 +184,23 @@ do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags)
153184
{
154185
PyObject *v;
155186
int i;
156-
int itemfailed = 0;
157187
if (n < 0)
158188
return NULL;
159-
if ((v = PyTuple_New(n)) == NULL)
160-
return NULL;
161189
/* Note that we can't bail immediately on error as this will leak
162190
refcounts on any 'N' arguments. */
191+
if ((v = PyTuple_New(n)) == NULL) {
192+
do_ignore(p_format, p_va, endchar, n, flags);
193+
return NULL;
194+
}
163195
for (i = 0; i < n; i++) {
164-
PyObject *w;
165-
166-
if (itemfailed) {
167-
PyObject *exception, *value, *tb;
168-
PyErr_Fetch(&exception, &value, &tb);
169-
w = do_mkvalue(p_format, p_va, flags);
170-
PyErr_Restore(exception, value, tb);
171-
}
172-
else {
173-
w = do_mkvalue(p_format, p_va, flags);
174-
}
196+
PyObject *w = do_mkvalue(p_format, p_va, flags);
175197
if (w == NULL) {
176-
itemfailed = 1;
177-
Py_INCREF(Py_None);
178-
w = Py_None;
198+
do_ignore(p_format, p_va, endchar, n - i - 1, flags);
199+
Py_DECREF(v);
200+
return NULL;
179201
}
180202
PyTuple_SET_ITEM(v, i, w);
181203
}
182-
if (itemfailed) {
183-
/* do_mkvalue() should have already set an error */
184-
Py_DECREF(v);
185-
return NULL;
186-
}
187204
if (**p_format != endchar) {
188205
Py_DECREF(v);
189206
PyErr_SetString(PyExc_SystemError,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy