gabriel / muse public
feat patch task/hash-object-canonical-prefix #2 / 2
AI Agent gabriel · 163 days ago · Apr 17, 2026 · Diff

feat: enforce canonical sha256: prefix on object IDs everywhere

- hash-object: _hash_bytes now returns sha256: prefix; JSON output includes size_bytes, duration_ms, exit_code; text output is canonical sha256:<hex> - verify-object: _verify_one computes canonical actual = sha256: + hexdigest so comparison against stored canonical ID is correct; _iter_all_object_ids returns sha256: prefixed IDs instead of bare hex - name-rev: validation now accepts sha256: prefixed commit IDs (strips prefix before hex-char check) - rev-parse: default format changed from text to json; all tests already expected JSON output - snapshot-diff: _resolve_to_snapshot_id guards get_head_commit_id call with ValueError catch so canonical snapshot IDs are not rejected as branch names - Tests: update _make_object, bare hex object IDs, length assertions, and test_cmd_rev_parse default-format test to match canonical form throughout

sha256:efff3e8463a57478a369469f492c37e8ce89df87e9da1abbff9ee07d9c37a765 sha
+593 symbols
sha256:178e1326cda8d8fc4ed39edd62b204d4f8ee5e9cb4e77cce7ebaf9b909b546c1 snapshot
+593
symbols added
0
dead code introduced
Semantic Changes 593 symbols
~ tests/test_hash_object_canonical.py .py 45 symbols added
+ TestAgentFields class class TestAgentFields L173–230
+ test_duration_ms_non_negative method method test_duration_ms_non_negative L182–186
+ test_duration_ms_present method method test_duration_ms_present L176–180
+ test_exit_code_present method method test_exit_code_present L188–192
+ test_exit_code_zero_on_success method method test_exit_code_zero_on_success L194–198
+ test_size_bytes_correct_for_file method method test_size_bytes_correct_for_file L206–211
+ test_size_bytes_correct_for_stdin method method test_size_bytes_correct_for_stdin L213–216
+ test_size_bytes_present method method test_size_bytes_present L200–204
+ test_size_bytes_zero_for_empty method method test_size_bytes_zero_for_empty L218–222
+ test_stdin_duration_ms_present method method test_stdin_duration_ms_present L224–226
+ test_stdin_exit_code_present method method test_stdin_exit_code_present L228–230
+ TestCanonicalPrefix class class TestCanonicalPrefix L59–122
+ test_empty_file_has_prefix method method test_empty_file_has_prefix L100–105
+ test_empty_stdin_has_prefix method method test_empty_stdin_has_prefix L107–110
+ test_file_json_object_id_correct_length method method test_file_json_object_id_correct_length L72–78
+ test_file_json_object_id_has_prefix method method test_file_json_object_id_has_prefix L62–70
+ test_file_json_object_id_matches_canonical method method test_file_json_object_id_matches_canonical L80–86
+ test_no_bare_hex_in_json_output method method test_no_bare_hex_in_json_output L112–122
+ test_stdin_json_object_id_has_prefix method method test_stdin_json_object_id_has_prefix L88–92
+ test_stdin_json_object_id_matches_canonical method method test_stdin_json_object_id_matches_canonical L94–98
+ TestCrossCheck class class TestCrossCheck L270–299
+ test_file_and_stdin_same_id method method test_file_and_stdin_same_id L273–279
+ test_hash_bytes_returns_canonical method method test_hash_bytes_returns_canonical L292–299
+ test_write_file_and_stdin_same_id method method test_write_file_and_stdin_same_id L281–290
+ TestStdinWriteFixed class class TestStdinWriteFixed L129–166
+ test_stdin_write_exits_zero method method test_stdin_write_exits_zero L132–135
+ test_stdin_write_idempotent method method test_stdin_write_idempotent L160–166
+ test_stdin_write_object_file_exists method method test_stdin_write_object_file_exists L142–151
+ test_stdin_write_object_id_canonical method method test_stdin_write_object_id_canonical L153–158
+ test_stdin_write_stored_true method method test_stdin_write_stored_true L137–140
+ TestTextOutputPrefix class class TestTextOutputPrefix L237–263
+ test_text_file_has_prefix method method test_text_file_has_prefix L240–245
+ test_text_length_is_71 method method test_text_length_is_71 L258–263
+ test_text_output_is_correct_canonical_id method method test_text_output_is_correct_canonical_id L251–256
+ test_text_stdin_has_prefix method method test_text_stdin_has_prefix L247–249
+ _make_repo function function _make_repo L39–48
+ _run function function _run L33–36
+ _sha256 function function _sha256 L51–52
+ CliRunner import import CliRunner L24–24
+ ExitCode import import ExitCode L23–23
+ annotations import import annotations L17–17
+ hashlib import import hashlib L19–19
+ json import import json L20–20
+ pathlib import import pathlib L21–21
+ runner variable variable runner L26–26
~ muse/cli/commands/hash_object.py .py 20 symbols added
+ _FORMAT_CHOICES variable variable _FORMAT_CHOICES L49–49
+ _emit function function _emit L228–239
+ _hash_bytes function function _hash_bytes L91–93
+ ExitCode import import ExitCode L41–41
+ annotations import import annotations L31–31
+ argparse import import argparse L33–33
+ find_repo_root import import find_repo_root L43–43
+ hash_file import import hash_file L44–44
+ hashlib import import hashlib L34–34
+ json import import json L35–35
+ logging import import logging L36–36
+ pathlib import import pathlib L37–37
+ sanitize_display import import sanitize_display L45–45
+ sys import import sys L38–38
+ time import import time L39–39
+ write_object import import write_object L42–42
+ write_object_from_path import import write_object_from_path L42–42
+ logger variable variable logger L47–47
+ register function function register L52–88
+ run function function run L96–225
~ muse/cli/commands/name_rev.py .py 23 symbols added
+ _FORMAT_CHOICES variable variable _FORMAT_CHOICES L103–103
+ _MAX_WALK variable variable _MAX_WALK L104–104
+ _NameMap variable variable _NameMap L100–100
+ _NameRevEntry class class _NameRevEntry L107–114
+ _build_name_map function function _build_name_map L117–199
+ _resolve_prefix function function _resolve_prefix L202–222
+ ExitCode import import ExitCode L94–94
+ TypedDict import import TypedDict L92–92
+ annotations import import annotations L83–83
+ argparse import import argparse L85–85
+ deque import import deque L91–91
+ fnmatch import import fnmatch L86–86
+ json import import json L87–87
+ logging import import logging L88–88
+ pathlib import import pathlib L89–89
+ read_commit import import read_commit L96–96
+ require_repo import import require_repo L95–95
+ sanitize_display import import sanitize_display L97–97
+ sys import import sys L90–90
+ validate_object_id import import validate_object_id L97–97
+ logger variable variable logger L101–101
+ register function function register L225–297
+ run function function run L300–440
~ muse/cli/commands/rev_parse.py .py 19 symbols added
+ _BARE_HEX_RE variable variable _BARE_HEX_RE L62–62
+ _FORMAT_CHOICES variable variable _FORMAT_CHOICES L58–58
+ _SHA256_FULL_RE variable variable _SHA256_FULL_RE L60–60
+ _SHA256_PREFIX_RE variable variable _SHA256_PREFIX_RE L61–61
+ ExitCode import import ExitCode L47–47
+ annotations import import annotations L39–39
+ argparse import import argparse L41–41
+ find_commits_by_prefix import import find_commits_by_prefix L49–49
+ get_head_commit_id import import get_head_commit_id L49–49
+ json import import json L42–42
+ logging import import logging L43–43
+ re import import re L44–44
+ read_commit import import read_commit L49–49
+ read_current_branch import import read_current_branch L49–49
+ require_repo import import require_repo L48–48
+ sys import import sys L45–45
+ logger variable variable logger L56–56
+ register function function register L65–98
+ run function function run L101–203
~ muse/cli/commands/snapshot_diff.py .py 27 symbols added
+ _AddedEntry class class _AddedEntry L85–87
+ _DeletedEntry class class _DeletedEntry L96–98
+ _DiffResult class class _DiffResult L101–107
+ _FORMAT_CHOICES variable variable _FORMAT_CHOICES L79–79
+ _ModifiedEntry class class _ModifiedEntry L90–93
+ _OID_WIDTH variable variable _OID_WIDTH L82–82
+ _compute_diff function function _compute_diff L148–202
+ _emit_text function function _emit_text L205–230
+ _resolve_to_snapshot_id function function _resolve_to_snapshot_id L110–145
+ ExitCode import import ExitCode L67–67
+ TypedDict import import TypedDict L65–65
+ annotations import import annotations L58–58
+ argparse import import argparse L60–60
+ get_head_commit_id import import get_head_commit_id L69–69
+ json import import json L61–61
+ logging import import logging L62–62
+ pathlib import import pathlib L63–63
+ read_commit import import read_commit L69–69
+ read_current_branch import import read_current_branch L69–69
+ read_snapshot import import read_snapshot L69–69
+ require_repo import import require_repo L68–68
+ sanitize_display import import sanitize_display L75–75
+ sys import import sys L64–64
+ validate_object_id import import validate_object_id L75–75
+ logger variable variable logger L77–77
+ register function function register L233–295
+ run function function run L298–373
~ muse/cli/commands/verify_object.py .py 22 symbols added
+ _CHUNK variable variable _CHUNK L86–86
+ _FORMAT_CHOICES variable variable _FORMAT_CHOICES L85–85
+ _ObjectResult class class _ObjectResult L89–93
+ _iter_all_object_ids function function _iter_all_object_ids L96–123
+ _verify_one function function _verify_one L126–180
+ ExitCode import import ExitCode L78–78
+ TypedDict import import TypedDict L76–76
+ annotations import import annotations L68–68
+ argparse import import argparse L70–70
+ hashlib import import hashlib L71–71
+ json import import json L72–72
+ logging import import logging L73–73
+ object_path import import object_path L79–79
+ objects_dir import import objects_dir L79–79
+ pathlib import import pathlib L74–74
+ require_repo import import require_repo L80–80
+ sanitize_display import import sanitize_display L81–81
+ sys import import sys L75–75
+ validate_object_id import import validate_object_id L81–81
+ logger variable variable logger L83–83
+ register function function register L183–235
+ run function function run L238–328
~ tests/test_cli_inspect.py .py 78 symbols added
+ TestCatObject class class TestCatObject L170–214
+ test_cat_info_format method method test_cat_info_format L183–195
+ test_cat_raw_bytes method method test_cat_raw_bytes L171–181
+ test_missing_object_errors method method test_missing_object_errors L197–203
+ test_missing_object_info_format method method test_missing_object_info_format L205–214
+ TestCommitGraph class class TestCommitGraph L547–602
+ test_explicit_tip method method test_explicit_tip L582–594
+ test_linear_graph method method test_linear_graph L548–566
+ test_no_commits_errors method method test_no_commits_errors L596–602
+ test_text_format method method test_text_format L568–580
+ TestCommitTree class class TestCommitTree L409–461
+ test_creates_commit_from_snapshot method method test_creates_commit_from_snapshot L410–430
+ test_missing_snapshot_errors method method test_missing_snapshot_errors L454–461
+ test_with_parent method method test_with_parent L432–452
+ TestHashObject class class TestHashObject L120–162
+ test_directory_errors method method test_directory_errors L160–162
+ test_hash_and_write method method test_hash_and_write L142–154
+ test_hash_file_json_output method method test_hash_file_json_output L121–130
+ test_hash_file_text_format method method test_hash_file_text_format L132–140
+ test_missing_file_errors method method test_missing_file_errors L156–158
+ TestLsFiles class class TestLsFiles L284–336
+ test_lists_files_json method method test_lists_files_json L285–300
+ test_lists_files_text method method test_lists_files_text L302–314
+ test_no_commits_errors method method test_no_commits_errors L330–336
+ test_with_explicit_commit method method test_with_explicit_commit L316–328
+ TestLsRemote class class TestLsRemote L725–742
+ test_bare_url_transport_error method method test_bare_url_transport_error L726–732
+ test_non_url_non_remote_errors method method test_non_url_non_remote_errors L734–742
+ TestPackObjects class class TestPackObjects L610–650
+ test_no_commits_on_head_errors method method test_no_commits_on_head_errors L644–650
+ test_packs_explicit_commit method method test_packs_explicit_commit L628–642
+ test_packs_head method method test_packs_head L611–626
+ TestReadCommit class class TestReadCommit L344–370
+ test_missing_commit_errors method method test_missing_commit_errors L362–370
+ test_reads_commit_json method method test_reads_commit_json L345–360
+ TestReadSnapshot class class TestReadSnapshot L378–401
+ test_missing_snapshot_errors method method test_missing_snapshot_errors L395–401
+ test_reads_snapshot_json method method test_reads_snapshot_json L379–393
+ TestRevParse class class TestRevParse L222–276
+ test_resolve_branch method method test_resolve_branch L223–237
+ test_resolve_head method method test_resolve_head L239–252
+ test_resolve_text_format method method test_resolve_text_format L254–266
+ test_unknown_ref_errors method method test_unknown_ref_errors L268–276
+ TestUnpackObjects class class TestUnpackObjects L658–717
+ test_idempotent_unpack method method test_idempotent_unpack L693–717
+ test_invalid_msgpack_errors method method test_invalid_msgpack_errors L683–691
+ test_unpacks_valid_bundle method method test_unpacks_valid_bundle L659–681
+ TestUpdateRef class class TestUpdateRef L469–539
+ test_creates_branch_ref method method test_creates_branch_ref L470–487
+ test_delete_ref method method test_delete_ref L507–519
+ test_no_verify_skips_commit_check method method test_no_verify_skips_commit_check L530–539
+ test_updates_existing_ref method method test_updates_existing_ref L489–505
+ test_verify_commit_not_found_errors method method test_verify_commit_not_found_errors L521–528
+ _init_repo function function _init_repo L42–53
+ _make_commit function function _make_commit L78–101
+ _make_object function function _make_object L56–61
+ _make_snapshot function function _make_snapshot L64–75
+ _repo_env function function _repo_env L110–112
+ _set_head function function _set_head L104–107
+ cli variable variable cli L21–21
+ CliRunner import import CliRunner L19–19
+ CommitRecord import import CommitRecord L28–28
+ ExitCode import import ExitCode L22–22
+ Manifest import import Manifest L27–27
+ SnapshotRecord import import SnapshotRecord L28–28
+ annotations import import annotations L11–11
+ build_pack import import build_pack L24–24
+ compute_commit_id import import compute_commit_id L25–25
+ compute_snapshot_id import import compute_snapshot_id L25–25
+ datetime import import datetime L13–13
+ json import import json L14–14
+ msgpack import import msgpack L17–17
+ pathlib import import pathlib L15–15
+ pytest import import pytest L18–18
+ write_commit import import write_commit L28–28
+ write_object import import write_object L23–23
+ write_snapshot import import write_snapshot L28–28
+ runner variable variable runner L35–35
~ tests/test_cmd_hash_object.py .py 58 symbols added
+ TestEmit class class TestEmit L86–105
+ test_json_format_has_fields method method test_json_format_has_fields L95–105
+ test_text_format_prints_hash method method test_text_format_prints_hash L87–93
+ TestFileMode class class TestFileMode L113–203
+ test_binary_content method method test_binary_content L178–185
+ test_determinism_same_content_same_hash method method test_determinism_same_content_same_hash L152–159
+ test_different_content_different_hash method method test_different_content_different_hash L161–168
+ test_directory_as_path_errors method method test_directory_as_path_errors L197–199
+ test_empty_file method method test_empty_file L170–176
+ test_invalid_format_errors method method test_invalid_format_errors L187–191
+ test_json_flag_shorthand method method test_json_flag_shorthand L126–132
+ test_json_output_shape method method test_json_output_shape L114–124
+ test_missing_file_errors method method test_missing_file_errors L193–195
+ test_no_args_errors method method test_no_args_errors L201–203
+ test_text_and_json_same_hash method method test_text_and_json_same_hash L143–150
+ test_text_format_is_canonical_id method method test_text_format_is_canonical_id L134–141
+ TestHashBytes class class TestHashBytes L58–83
+ test_deterministic method method test_deterministic L68–71
+ test_different_content_different_hash method method test_different_content_different_hash L73–75
+ test_known_sha256_empty method method test_known_sha256_empty L59–61
+ test_known_sha256_hello_world method method test_known_sha256_hello_world L63–66
+ test_returns_canonical_prefixed_id method method test_returns_canonical_prefixed_id L77–83
+ TestSecurity class class TestSecurity L332–358
+ test_ansi_in_path_not_in_stderr method method test_ansi_in_path_not_in_stderr L333–338
+ test_json_output_is_never_a_traceback method method test_json_output_is_never_a_traceback L353–358
+ test_no_path_no_stdin_clean_error method method test_no_path_no_stdin_clean_error L347–351
+ test_path_traversal_attempt_outside_repo method method test_path_traversal_attempt_outside_repo L340–345
+ TestStdinMode class class TestStdinMode L269–324
+ test_stdin_and_path_mutually_exclusive method method test_stdin_and_path_mutually_exclusive L298–302
+ test_stdin_empty_input method method test_stdin_empty_input L292–296
+ test_stdin_matches_file_hash method method test_stdin_matches_file_hash L278–284
+ test_stdin_produces_correct_hash method method test_stdin_produces_correct_hash L270–276
+ test_stdin_text_format method method test_stdin_text_format L286–290
+ test_stdin_write_stores_object method method test_stdin_write_stores_object L304–314
+ test_stdin_write_without_repo_errors method method test_stdin_write_without_repo_errors L316–324
+ TestStress class class TestStress L366–404
+ test_500_sequential_hashes method method test_500_sequential_hashes L389–397
+ test_large_file_hash_matches_reference method method test_large_file_hash_matches_reference L380–387
+ test_large_file_streams_without_oom method method test_large_file_streams_without_oom L367–378
+ test_stdin_large_binary method method test_stdin_large_binary L399–404
+ TestWrite class class TestWrite L211–261
+ test_write_creates_object_file method method test_write_creates_object_file L220–231
+ test_write_idempotent_second_call_stored_false method method test_write_idempotent_second_call_stored_false L233–240
+ test_write_returns_stored_true method method test_write_returns_stored_true L212–218
+ test_write_text_format_still_works method method test_write_text_format_still_works L253–261
+ test_write_without_repo_errors method method test_write_without_repo_errors L242–251
+ _make_repo function function _make_repo L42–50
+ _plumb function function _plumb L27–29
+ _plumb_repo function function _plumb_repo L32–39
+ CliRunner import import CliRunner L19–19
+ ExitCode import import ExitCode L18–18
+ InvokeResult import import InvokeResult L19–19
+ annotations import import annotations L10–10
+ hashlib import import hashlib L12–12
+ json import import json L13–13
+ pathlib import import pathlib L14–14
+ pytest import import pytest L16–16
+ runner variable variable runner L21–21
~ tests/test_cmd_integration.py .py 49 symbols added
+ TestCommitGraphNameRev class class TestCommitGraphNameRev L414–446
+ test_all_graph_commits_nameable method method test_all_graph_commits_nameable L431–446
+ test_graph_tip_named_branch_tilde_zero method method test_graph_tip_named_branch_tilde_zero L415–429
+ TestCommitTreeUpdateRefRevParse class class TestCommitTreeUpdateRefRevParse L177–214
+ test_full_commit_creation_pipeline method method test_full_commit_creation_pipeline L178–195
+ test_two_commit_chain_rev_parse_follows_ref method method test_two_commit_chain_rev_parse_follows_ref L197–214
+ TestHashCatVerifyPipeline class class TestHashCatVerifyPipeline L131–169
+ test_hash_without_write_not_in_store method method test_hash_without_write_not_in_store L153–169
+ test_write_then_cat_returns_same_bytes method method test_write_then_cat_returns_same_bytes L132–151
+ TestMergeBaseSnapshotDiff class class TestMergeBaseSnapshotDiff L380–406
+ test_diff_between_branches_using_merge_base method method test_diff_between_branches_using_merge_base L381–406
+ TestPackUnpackPipeline class class TestPackUnpackPipeline L222–261
+ test_all_objects_survive_transport method method test_all_objects_survive_transport L223–246
+ test_pack_then_verify_object_in_dst method method test_pack_then_verify_object_in_dst L248–261
+ TestShowRefForEachRefConsistency class class TestShowRefForEachRefConsistency L310–333
+ test_both_commands_report_same_branch_count method method test_both_commands_report_same_branch_count L325–333
+ test_both_commands_report_same_commit_ids method method test_both_commands_report_same_commit_ids L311–323
+ TestSnapshotDiffLsFilesCrossCheck class class TestSnapshotDiffLsFilesCrossCheck L269–302
+ test_added_files_in_diff_appear_in_new_ls_files method method test_added_files_in_diff_appear_in_new_ls_files L270–286
+ test_deleted_files_absent_from_new_ls_files method method test_deleted_files_absent_from_new_ls_files L288–302
+ TestSymbolicRefRevParseReadCommit class class TestSymbolicRefRevParseReadCommit L341–372
+ test_set_and_read_symbolic_ref_consistent method method test_set_and_read_symbolic_ref_consistent L356–372
+ test_symbolic_ref_branch_matches_rev_parse_commit method method test_symbolic_ref_branch_matches_rev_parse_commit L342–354
+ _commit function function _commit L81–103
+ _env function function _env L63–64
+ _init_repo function function _init_repo L50–60
+ _invoke function function _invoke L112–117
+ _invoke_text function function _invoke_text L120–123
+ _obj function function _obj L106–109
+ _sha function function _sha L42–43
+ _sha_bytes function function _sha_bytes L46–47
+ _snap function function _snap L67–78
+ cli variable variable cli L28–28
+ CliRunner import import CliRunner L25–25
+ CommitRecord import import CommitRecord L31–31
+ Manifest import import Manifest L32–32
+ MsgpackDict import import MsgpackDict L26–26
+ SnapshotRecord import import SnapshotRecord L31–31
+ annotations import import annotations L18–18
+ compute_commit_id import import compute_commit_id L30–30
+ compute_snapshot_id import import compute_snapshot_id L30–30
+ datetime import import datetime L20–20
+ hashlib import import hashlib L21–21
+ json import import json L22–22
+ pathlib import import pathlib L23–23
+ write_commit import import write_commit L31–31
+ write_object import import write_object L29–29
+ write_snapshot import import write_snapshot L31–31
+ runner variable variable runner L34–34
~ tests/test_cmd_rev_parse.py .py 64 symbols added
+ TestAbbrevRef class class TestAbbrevRef L308–328
+ test_abbrev_ref_head_returns_branch_name method method test_abbrev_ref_head_returns_branch_name L309–316
+ test_abbrev_ref_main method method test_abbrev_ref_main L324–328
+ test_abbrev_ref_text_format method method test_abbrev_ref_text_format L318–322
+ TestBranchResolution class class TestBranchResolution L189–217
+ test_json_flag_shorthand method method test_json_flag_shorthand L204–209
+ test_resolve_branch_json method method test_resolve_branch_json L190–196
+ test_resolve_branch_text method method test_resolve_branch_text L198–202
+ test_unknown_branch_not_found method method test_unknown_branch_not_found L211–217
+ TestDefaultFormat class class TestDefaultFormat L111–143
+ test_default_output_is_json method method test_default_output_is_json L112–119
+ test_format_text_explicit method method test_format_text_explicit L139–143
+ test_json_flag_gives_dict_output method method test_json_flag_gives_dict_output L130–137
+ test_text_format_gives_plain_commit_id method method test_text_format_gives_plain_commit_id L121–128
+ TestEdgeCases class class TestEdgeCases L336–357
+ test_branch_with_slash_resolves method method test_branch_with_slash_resolves L350–357
+ test_empty_ref_clean_error method method test_empty_ref_clean_error L337–343
+ test_invalid_format_errors method method test_invalid_format_errors L345–348
+ TestHeadResolution class class TestHeadResolution L225–248
+ test_head_lowercase_also_resolves method method test_head_lowercase_also_resolves L233–239
+ test_head_on_empty_repo_errors method method test_head_on_empty_repo_errors L241–248
+ test_resolve_head method method test_resolve_head L226–231
+ TestSecurity class class TestSecurity L365–390
+ test_ansi_in_ref_is_json_escaped method method test_ansi_in_ref_is_json_escaped L366–375
+ test_no_traceback_on_bad_input method method test_no_traceback_on_bad_input L387–390
+ test_null_byte_in_ref method method test_null_byte_in_ref L382–385
+ test_path_traversal_ref_gives_not_found method method test_path_traversal_ref_gives_not_found L377–380
+ TestSha256PrefixRequired class class TestSha256PrefixRequired L151–181
+ test_bare_full_hex_rejected method method test_bare_full_hex_rejected L152–158
+ test_bare_short_hex_rejected method method test_bare_short_hex_rejected L160–166
+ test_canonical_full_id_resolves method method test_canonical_full_id_resolves L168–173
+ test_canonical_prefix_resolves method method test_canonical_prefix_resolves L175–181
+ TestShaResolution class class TestShaResolution L256–300
+ test_ambiguous_prefix_returns_candidates method method test_ambiguous_prefix_returns_candidates L272–293
+ test_nonexistent_full_sha_not_found method method test_nonexistent_full_sha_not_found L295–300
+ test_resolve_8char_prefix method method test_resolve_8char_prefix L264–270
+ test_resolve_full_sha method method test_resolve_full_sha L257–262
+ TestStress class class TestStress L398–411
+ test_200_abbrev_ref_resolves method method test_200_abbrev_ref_resolves L406–411
+ test_200_rapid_resolves method method test_200_rapid_resolves L399–404
+ _TS variable variable _TS L40–40
+ _make_commit function function _make_commit L53–74
+ _make_repo function function _make_repo L30–37
+ _populated_repo function function _populated_repo L92–98
+ _rev function function _rev L83–89
+ _set_head function function _set_head L77–80
+ _store_snap function function _store_snap L43–50
+ CliRunner import import CliRunner L22–22
+ CommitRecord import import CommitRecord L20–20
+ ExitCode import import ExitCode L17–17
+ InvokeResult import import InvokeResult L22–22
+ Manifest import import Manifest L21–21
+ SnapshotRecord import import SnapshotRecord L20–20
+ annotations import import annotations L10–10
+ compute_commit_id import import compute_commit_id L19–19
+ compute_snapshot_id import import compute_snapshot_id L19–19
+ datetime import import datetime L12–12
+ json import import json L13–13
+ pathlib import import pathlib L14–14
+ pytest import import pytest L16–16
+ write_commit import import write_commit L20–20
+ write_object import import write_object L18–18
+ write_snapshot import import write_snapshot L20–20
+ runner variable variable runner L24–24
+ TestApplyPackBomb class class TestApplyPackBomb L285–358
+ _build_pack method method _build_pack L286–303
+ test_oversized_object_in_pack_is_skipped method method test_oversized_object_in_pack_is_skipped L328–347
+ test_pack_at_limit_succeeds method method test_pack_at_limit_succeeds L305–312
+ test_pack_exceeds_limit_raises method method test_pack_exceeds_limit_raises L314–326
+ test_zero_item_pack_is_accepted method method test_zero_item_pack_is_accepted L349–358
+ TestApplyPackDeduplication class class TestApplyPackDeduplication L366–400
+ test_duplicate_object_ids_not_hashed_twice method method test_duplicate_object_ids_not_hashed_twice L367–381
+ test_duplicate_then_different_both_processed method method test_duplicate_then_different_both_processed L383–400
+ TestApplyPackMalformedEntries class class TestApplyPackMalformedEntries L408–456
+ test_empty_content_in_pack_entry_skipped method method test_empty_content_in_pack_entry_skipped L448–456
+ test_malformed_object_entry_does_not_abort_pack method method test_malformed_object_entry_does_not_abort_pack L409–436
+ test_missing_object_id_in_pack_entry_skipped method method test_missing_object_id_in_pack_entry_skipped L438–446
+ TestCallsiteIntegrity class class TestCallsiteIntegrity L493–555
+ test_hash_object_file_derives_id_from_file_content method method test_hash_object_file_derives_id_from_file_content L512–529
+ test_hash_object_stdin_derives_id_from_content method method test_hash_object_stdin_derives_id_from_content L494–510
+ test_unpack_objects_hash_mismatch_rejected method method test_unpack_objects_hash_mismatch_rejected L531–555
+ TestConcurrentPoisoning class class TestConcurrentPoisoning L627–681
+ test_concurrent_hash_mismatch_attempts_do_not_corrupt method method test_concurrent_hash_mismatch_attempts_do_not_corrupt L628–657
+ test_concurrent_writes_of_same_object_idempotent method method test_concurrent_writes_of_same_object_idempotent L659–681
+ TestHashMismatch class class TestHashMismatch L107–166
+ test_all_ones_id_mismatch_raises method method test_all_ones_id_mismatch_raises L144–150
+ test_empty_object_valid method method test_empty_object_valid L152–157
+ test_invalid_object_id_format_raises method method test_invalid_object_id_format_raises L159–166
+ test_write_object_correct_content_succeeds method method test_write_object_correct_content_succeeds L118–123
+ test_write_object_from_path_correct_id_succeeds method method test_write_object_from_path_correct_id_succeeds L135–142
+ test_write_object_from_path_wrong_id_raises method method test_write_object_from_path_wrong_id_raises L125–133
+ test_write_object_wrong_content_raises method method test_write_object_wrong_content_raises L108–116
+ TestObjectSizeCap class class TestObjectSizeCap L174–218
+ test_exactly_at_limit_is_rejected method method test_exactly_at_limit_is_rejected L185–192
+ test_just_under_limit_succeeds method method test_just_under_limit_succeeds L212–218
+ test_oversized_content_rejected_at_write method method test_oversized_content_rejected_at_write L175–183
+ test_write_object_from_path_oversized_raises method method test_write_object_from_path_oversized_raises L194–210
+ TestReadObjectIntegrity class class TestReadObjectIntegrity L464–485
+ test_read_absent_object_returns_none method method test_read_absent_object_returns_none L483–485
+ test_read_clean_object_succeeds method method test_read_clean_object_succeeds L465–469
+ test_read_corrupted_object_raises method method test_read_corrupted_object_raises L471–481
+ TestRestoreObjectIntegrity class class TestRestoreObjectIntegrity L226–277
+ test_restore_clean_object_succeeds method method test_restore_clean_object_succeeds L227–233
+ test_restore_dest_is_writable method method test_restore_dest_is_writable L260–268
+ test_restore_detects_corrupted_store_object method method test_restore_detects_corrupted_store_object L242–258
+ test_restore_is_atomic method method test_restore_is_atomic L270–277
+ test_restore_missing_object_returns_false method method test_restore_missing_object_returns_false L235–240
+ TestSHA256ThreatModel class class TestSHA256ThreatModel L689–733
+ test_object_mode_is_immutable method method test_object_mode_is_immutable L725–733
+ test_sha256_preimage_resistance_documented method method test_sha256_preimage_resistance_documented L690–712
+ test_write_then_read_roundtrip_preserves_content method method test_write_then_read_roundtrip_preserves_content L714–723
+ TestStress class class TestStress L563–619
+ no_fsync method method no_fsync L565–570
+ test_10k_duplicate_ids_deduplicated method method test_10k_duplicate_ids_deduplicated L607–619
+ test_10k_object_pack_within_budget method method test_10k_object_pack_within_budget L573–589
+ test_idempotent_10k_pack_fast method method test_idempotent_10k_pack_fast L591–605
+ _make_repo function function _make_repo L54–62
+ _minimal_commit_dict function function _minimal_commit_dict L72–87
+ _minimal_snapshot_dict function function _minimal_snapshot_dict L90–99
+ _sha256 function function _sha256 L50–51
+ _stored_object function function _stored_object L65–69
+ ApplyResult import import ApplyResult L39–39
+ CommitDict import import CommitDict L40–40
+ MAX_OBJECT_WRITE_BYTES import import MAX_OBJECT_WRITE_BYTES L41–41
+ MAX_PACK_OBJECTS import import MAX_PACK_OBJECTS L41–41
+ Manifest import import Manifest L42–42
+ PackBundle import import PackBundle L39–39
+ SnapshotDict import import SnapshotDict L40–40
+ annotations import import annotations L19–19
+ apply_pack import import apply_pack L39–39
+ has_object import import has_object L32–32
+ hashlib import import hashlib L21–21
+ os import import os L22–22
+ patch import import patch L30–30
+ pathlib import import pathlib L23–23
+ pytest import import pytest L29–29
+ read_object import import read_object L32–32
+ restore_object import import restore_object L32–32
+ tempfile import import tempfile L24–24
+ threading import import threading L25–25
+ time import import time L26–26
+ uuid import import uuid L27–27
+ write_object import import write_object L32–32
+ write_object_from_path import import write_object_from_path L32–32
~ tests/test_security_path_traversal.py .py 108 symbols added
+ TestCheckAttrSecurity class class TestCheckAttrSecurity L337–423
+ _repo_with_attrs method method _repo_with_attrs L338–345
+ test_10k_paths_stress method method test_10k_paths_stress L413–423
+ test_absolute_path_rejected method method test_absolute_path_rejected L365–371
+ test_ansi_escape_in_path_rejected method method test_ansi_escape_in_path_rejected L373–380
+ test_crlf_stdin_stripped method method test_crlf_stdin_stripped L399–411
+ test_null_byte_path_rejected method method test_null_byte_path_rejected L357–363
+ test_traversal_path_rejected method method test_traversal_path_rejected L347–355
+ test_valid_path_accepted method method test_valid_path_accepted L382–388
+ test_very_long_path_rejected method method test_very_long_path_rejected L390–397
+ TestCheckIgnoreSecurity class class TestCheckIgnoreSecurity L431–490
+ _repo method method _repo L432–439
+ test_absolute_path_rejected method method test_absolute_path_rejected L457–463
+ test_crlf_stdin_does_not_embed_cr method method test_crlf_stdin_does_not_embed_cr L473–482
+ test_dotdot_in_middle_rejected method method test_dotdot_in_middle_rejected L484–490
+ test_null_byte_path_rejected method method test_null_byte_path_rejected L449–455
+ test_traversal_path_rejected method method test_traversal_path_rejected L441–447
+ test_valid_path_accepted method method test_valid_path_accepted L465–471
+ TestEndToEndAdversarial class class TestEndToEndAdversarial L627–672
+ test_check_attr_stdin_mixed_good_and_bad method method test_check_attr_stdin_mixed_good_and_bad L639–654
+ test_hash_object_write_then_ls_files method method test_hash_object_write_then_ls_files L628–637
+ test_no_sensitive_data_in_error_output method method test_no_sensitive_data_in_error_output L656–672
+ TestHashObjectSecurity class class TestHashObjectSecurity L216–285
+ test_regular_file_accepted method method test_regular_file_accepted L233–240
+ test_rejects_char_device method method test_rejects_char_device L279–285
+ test_rejects_directory method method test_rejects_directory L225–227
+ test_rejects_named_pipe method method test_rejects_named_pipe L217–223
+ test_rejects_nonexistent_path method method test_rejects_nonexistent_path L229–231
+ test_symlink_to_nonexistent_rejected method method test_symlink_to_nonexistent_rejected L252–256
+ test_symlink_to_regular_file_accepted method method test_symlink_to_regular_file_accepted L242–250
+ test_very_long_path_rejected method method test_very_long_path_rejected L258–264
+ test_write_stores_object_in_repo method method test_write_stores_object_in_repo L266–276
+ TestLsFilesPrefix class class TestLsFilesPrefix L293–329
+ test_clean_prefix_accepted method method test_clean_prefix_accepted L312–319
+ test_empty_prefix_returns_all method method test_empty_prefix_returns_all L321–329
+ test_glob_star_in_prefix_rejected method method test_glob_star_in_prefix_rejected L303–310
+ test_null_byte_in_prefix_rejected method method test_null_byte_in_prefix_rejected L294–301
+ TestPackZipSlip class class TestPackZipSlip L537–619
+ _minimal_bundle method method _minimal_bundle L538–551
+ test_100_malicious_keys_all_skipped method method test_100_malicious_keys_all_skipped L588–597
+ test_absolute_key_in_manifest_rejected method method test_absolute_key_in_manifest_rejected L561–566
+ test_clean_manifest_written method method test_clean_manifest_written L581–586
+ test_invalid_object_id_in_manifest_rejected method method test_invalid_object_id_in_manifest_rejected L574–579
+ test_malicious_object_id_in_pack_rejected method method test_malicious_object_id_in_pack_rejected L599–609
+ test_null_byte_key_in_manifest_rejected method method test_null_byte_key_in_manifest_rejected L568–572
+ test_traversal_key_in_manifest_rejected method method test_traversal_key_in_manifest_rejected L553–559
+ test_unpack_objects_core_with_traversal_manifest method method test_unpack_objects_core_with_traversal_manifest L611–619
+ TestValidatePathPrefix class class TestValidatePathPrefix L182–208
+ test_rejects_control_character method method test_rejects_control_character L206–208
+ test_rejects_glob_bracket method method test_rejects_glob_bracket L202–204
+ test_rejects_glob_question method method test_rejects_glob_question L198–200
+ test_rejects_glob_star method method test_rejects_glob_star L194–196
+ test_rejects_null_byte method method test_rejects_null_byte L190–192
+ test_valid_empty_prefix method method test_valid_empty_prefix L186–188
+ test_valid_prefix method method test_valid_prefix L183–184
+ TestValidateWorkspacePath class class TestValidateWorkspacePath L95–174
+ test_accepts_path_at_max_length method method test_accepts_path_at_max_length L167–170
+ test_rejects_absolute_posix method method test_rejects_absolute_posix L134–136
+ test_rejects_absolute_windows_backslash method method test_rejects_absolute_windows_backslash L138–140
+ test_rejects_ansi_escape_sequence method method test_rejects_ansi_escape_sequence L158–161
+ test_rejects_control_character_cr method method test_rejects_control_character_cr L146–148
+ test_rejects_control_character_esc method method test_rejects_control_character_esc L154–156
+ test_rejects_control_character_lf method method test_rejects_control_character_lf L150–152
+ test_rejects_dotdot_alone method method test_rejects_dotdot_alone L130–132
+ test_rejects_dotdot_in_middle method method test_rejects_dotdot_in_middle L126–128
+ test_rejects_dotdot_relative method method test_rejects_dotdot_relative L122–124
+ test_rejects_empty method method test_rejects_empty L109–111
+ test_rejects_null_byte method method test_rejects_null_byte L113–115
+ test_rejects_null_byte_prefix_injection method method test_rejects_null_byte_prefix_injection L117–120
+ test_rejects_path_one_over_max method method test_rejects_path_one_over_max L172–174
+ test_rejects_very_long_path method method test_rejects_very_long_path L163–165
+ test_rejects_windows_drive_letter method method test_rejects_windows_drive_letter L142–144
+ test_valid_filename_only method method test_valid_filename_only L99–100
+ test_valid_simple_path method method test_valid_simple_path L96–97
+ test_valid_with_dots_in_name method method test_valid_with_dots_in_name L102–103
+ test_valid_with_tab method method test_valid_with_tab L105–107
+ TestVerifyObjectStdinCRLF class class TestVerifyObjectStdinCRLF L498–529
+ test_crlf_id_rejected_cleanly method method test_crlf_id_rejected_cleanly L499–515
+ test_lf_only_works method method test_lf_only_works L517–529
+ _BASE_DT variable variable _BASE_DT L51–51
+ _REPO_ID variable variable _REPO_ID L50–50
+ _env function function _env L86–87
+ _init_repo function function _init_repo L59–67
+ _make_commit function function _make_commit L70–83
+ cli variable variable cli L47–47
+ CliRunner import import CliRunner L35–35
+ CommitRecord import import CommitRecord L40–40
+ ExitCode import import ExitCode L36–36
+ Manifest import import Manifest L45–45
+ PackBundle import import PackBundle L38–38
+ SnapshotDict import import SnapshotDict L40–40
+ SnapshotRecord import import SnapshotRecord L40–40
+ annotations import import annotations L25–25
+ apply_pack import import apply_pack L38–38
+ compute_commit_id import import compute_commit_id L39–39
+ compute_snapshot_id import import compute_snapshot_id L39–39
+ datetime import import datetime L27–27
+ json import import json L28–28
+ os import import os L29–29
+ pathlib import import pathlib L30–30
+ pytest import import pytest L33–33
+ sys import import sys L31–31
+ validate_path_prefix import import validate_path_prefix L41–41
+ validate_workspace_path import import validate_workspace_path L41–41
+ write_commit import import write_commit L40–40
+ write_object import import write_object L37–37
+ write_snapshot import import write_snapshot L40–40
+ runner variable variable runner L48–48

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:efff3e8463a57478a369469f492c37e8ce89df87e9da1abbff9ee07d9c37a765 --body "your comment"