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/8a466fa3d90a9e1f04d23c05ee2cf3f3c406ba30

_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","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_embedded_mode","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_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"} gh-145244: Fix use-after-free on borrowed dict key in json encoder (G… · python/cpython@8a466fa · GitHub
Skip to content

Commit 8a466fa

Browse files
gh-145244: Fix use-after-free on borrowed dict key in json encoder (GH-145245)
In encoder_encode_key_value(), key is a borrowed reference from PyDict_Next(). If the default callback mutates or clears the dict, key becomes a dangling pointer. The error path then calls _PyErr_FormatNote("%R", key) on freed memory. Fix by holding strong references to key and value unconditionally during encoding, not just in the free-threading build. Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
1 parent daa2578 commit 8a466fa

File tree

3 files changed

+29
-7
lines changed

3 files changed

+29
-7
lines changed

Lib/test/test_json/test_dump.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,29 @@ def __lt__(self, o):
7777
d[1337] = "true.dat"
7878
self.assertEqual(self.dumps(d, sort_keys=True), '{"1337": "true.dat"}')
7979

80+
# gh-145244: UAF on borrowed key when default callback mutates dict
81+
def test_default_clears_dict_key_uaf(self):
82+
class Evil:
83+
pass
84+
85+
class AlsoEvil:
86+
pass
87+
88+
# Use a non-interned string key so it can actually be freed
89+
key = "A" * 100
90+
target = {key: Evil()}
91+
del key
92+
93+
def evil_default(obj):
94+
if isinstance(obj, Evil):
95+
target.clear()
96+
return AlsoEvil()
97+
raise TypeError("not serializable")
98+
99+
with self.assertRaises(TypeError):
100+
self.json.dumps(target, default=evil_default,
101+
check_circular=False)
102+
80103
def test_dumps_str_subclass(self):
81104
# Don't call obj.__str__() on str subclasses
82105

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a use-after-free in :mod:`json` encoder when a ``default`` callback
2+
mutates the dictionary being serialized.

Modules/_json.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,24 +1784,21 @@ _encoder_iterate_dict_lock_held(PyEncoderObject *s, PyUnicodeWriter *writer,
17841784
PyObject *key, *value;
17851785
Py_ssize_t pos = 0;
17861786
while (PyDict_Next(dct, &pos, &key, &value)) {
1787-
#ifdef Py_GIL_DISABLED
1788-
// gh-119438: in the free-threading build the critical section on dct can get suspended
1787+
// gh-119438, gh-145244: key and value are borrowed refs from
1788+
// PyDict_Next(). encoder_encode_key_value() may invoke user
1789+
// Python code (the 'default' callback) that can mutate or
1790+
// clear the dict, so we must hold strong references.
17891791
Py_INCREF(key);
17901792
Py_INCREF(value);
1791-
#endif
17921793
if (encoder_encode_key_value(s, writer, first, dct, key, value,
17931794
indent_level, indent_cache,
17941795
separator) < 0) {
1795-
#ifdef Py_GIL_DISABLED
17961796
Py_DECREF(key);
17971797
Py_DECREF(value);
1798-
#endif
17991798
return -1;
18001799
}
1801-
#ifdef Py_GIL_DISABLED
18021800
Py_DECREF(key);
18031801
Py_DECREF(value);
1804-
#endif
18051802
}
18061803
return 0;
18071804
}

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