hgitaly 18.2.2__tar.gz → 18.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. {hgitaly-18.2.2/hgitaly.egg-info → hgitaly-18.2.3}/PKG-INFO +1 -1
  2. hgitaly-18.2.3/hgitaly/VERSION +1 -0
  3. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/operations.py +35 -38
  4. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_operations.py +16 -1
  5. {hgitaly-18.2.2 → hgitaly-18.2.3/hgitaly.egg-info}/PKG-INFO +1 -1
  6. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_operations.py +2 -3
  7. hgitaly-18.2.2/hgitaly/VERSION +0 -1
  8. {hgitaly-18.2.2 → hgitaly-18.2.3}/LICENSE +0 -0
  9. {hgitaly-18.2.2 → hgitaly-18.2.3}/MANIFEST.in +0 -0
  10. {hgitaly-18.2.2 → hgitaly-18.2.3}/README.md +0 -0
  11. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgext3rd/__init__.py +0 -0
  12. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgext3rd/hgitaly/__init__.py +0 -0
  13. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgext3rd/hgitaly/revset.py +0 -0
  14. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgext3rd/hgitaly/tests/__init__.py +0 -0
  15. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgext3rd/hgitaly/tests/test_revset.py +0 -0
  16. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgext3rd/hgitaly/tests/test_serve.py +0 -0
  17. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/__init__.py +0 -0
  18. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/branch.py +0 -0
  19. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/changelog.py +0 -0
  20. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/diff.py +0 -0
  21. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/errors.py +0 -0
  22. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/feature.py +0 -0
  23. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/file_content.py +0 -0
  24. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/file_context.py +0 -0
  25. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/git.py +0 -0
  26. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/gitlab_ref.py +0 -0
  27. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/identification.py +0 -0
  28. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/logging.py +0 -0
  29. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/manifest.py +0 -0
  30. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/message.py +0 -0
  31. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/oid.py +0 -0
  32. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/pagination.py +0 -0
  33. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/path.py +0 -0
  34. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/peer.py +0 -0
  35. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/procutil.py +0 -0
  36. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/repository.py +0 -0
  37. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/revision.py +0 -0
  38. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/revset.py +0 -0
  39. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/scripts.py +0 -0
  40. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/__init__.py +0 -0
  41. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/address.py +0 -0
  42. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/mono.py +0 -0
  43. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/prefork.py +0 -0
  44. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/tests/__init__.py +0 -0
  45. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/tests/test_address.py +0 -0
  46. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/tests/test_mono.py +0 -0
  47. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/tests/test_prefork.py +0 -0
  48. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/tests/test_worker.py +0 -0
  49. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/server/worker.py +0 -0
  50. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/__init__.py +0 -0
  51. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/analysis.py +0 -0
  52. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/blob.py +0 -0
  53. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/commit.py +0 -0
  54. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/diff.py +0 -0
  55. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/interceptors.py +0 -0
  56. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/mercurial_changeset.py +0 -0
  57. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/mercurial_operations.py +0 -0
  58. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/mercurial_repository.py +0 -0
  59. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/ref.py +0 -0
  60. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/repository.py +0 -0
  61. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/server.py +0 -0
  62. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/__init__.py +0 -0
  63. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/fixture.py +0 -0
  64. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_analysis.py +0 -0
  65. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_blob.py +0 -0
  66. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_commit.py +0 -0
  67. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_default_branch.py +0 -0
  68. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_diff.py +0 -0
  69. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_mercurial_changeset.py +0 -0
  70. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_mercurial_operations.py +0 -0
  71. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_mercurial_repository.py +0 -0
  72. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_ref.py +0 -0
  73. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_repository_service.py +0 -0
  74. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/service/tests/test_server.py +0 -0
  75. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/servicer.py +0 -0
  76. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/ssh.py +0 -0
  77. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stream.py +0 -0
  78. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/__init__.py +0 -0
  79. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/analysis_pb2.py +0 -0
  80. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/analysis_pb2_grpc.py +0 -0
  81. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/blob_pb2.py +0 -0
  82. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/blob_pb2_grpc.py +0 -0
  83. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/commit_pb2.py +0 -0
  84. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/commit_pb2_grpc.py +0 -0
  85. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/diff_pb2.py +0 -0
  86. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/diff_pb2_grpc.py +0 -0
  87. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/errors_pb2.py +0 -0
  88. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/errors_pb2_grpc.py +0 -0
  89. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/lint_pb2.py +0 -0
  90. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/lint_pb2_grpc.py +0 -0
  91. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/mercurial_aux_git_pb2.py +0 -0
  92. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/mercurial_aux_git_pb2_grpc.py +0 -0
  93. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/mercurial_changeset_pb2.py +0 -0
  94. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/mercurial_changeset_pb2_grpc.py +0 -0
  95. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/mercurial_operations_pb2.py +0 -0
  96. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/mercurial_operations_pb2_grpc.py +0 -0
  97. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/mercurial_repository_pb2.py +0 -0
  98. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/mercurial_repository_pb2_grpc.py +0 -0
  99. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/operations_pb2.py +0 -0
  100. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/operations_pb2_grpc.py +0 -0
  101. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/ref_pb2.py +0 -0
  102. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/ref_pb2_grpc.py +0 -0
  103. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/remote_pb2.py +0 -0
  104. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/remote_pb2_grpc.py +0 -0
  105. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/repository_pb2.py +0 -0
  106. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/repository_pb2_grpc.py +0 -0
  107. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/server_pb2.py +0 -0
  108. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/server_pb2_grpc.py +0 -0
  109. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/shared_pb2.py +0 -0
  110. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/stub/shared_pb2_grpc.py +0 -0
  111. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tag.py +0 -0
  112. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/__init__.py +0 -0
  113. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/bundle.py +0 -0
  114. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/context.py +0 -0
  115. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/grpc.py +0 -0
  116. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/multiprocessing.py +0 -0
  117. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/ssh.py +0 -0
  118. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/sshd.py +0 -0
  119. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/storage.py +0 -0
  120. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/tests/__init__.py +0 -0
  121. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/testing/tests/test_sshd.py +0 -0
  122. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/__init__.py +0 -0
  123. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/common.py +0 -0
  124. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_branch.py +0 -0
  125. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_diff.py +0 -0
  126. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_errors.py +0 -0
  127. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_feature.py +0 -0
  128. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_file_context.py +0 -0
  129. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_gitlab_ref.py +0 -0
  130. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_identification.py +0 -0
  131. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_manifest.py +0 -0
  132. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_messages.py +0 -0
  133. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_oid.py +0 -0
  134. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_peer.py +0 -0
  135. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_repository.py +0 -0
  136. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_revision.py +0 -0
  137. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_revset.py +0 -0
  138. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_servicer.py +0 -0
  139. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_stream.py +0 -0
  140. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_tag.py +0 -0
  141. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/tests/test_workdir.py +0 -0
  142. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/util.py +0 -0
  143. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly/workdir.py +0 -0
  144. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly.egg-info/SOURCES.txt +0 -0
  145. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly.egg-info/dependency_links.txt +0 -0
  146. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly.egg-info/entry_points.txt +0 -0
  147. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly.egg-info/requires.txt +0 -0
  148. {hgitaly-18.2.2 → hgitaly-18.2.3}/hgitaly.egg-info/top_level.txt +0 -0
  149. {hgitaly-18.2.2 → hgitaly-18.2.3}/install-requirements.txt +0 -0
  150. {hgitaly-18.2.2 → hgitaly-18.2.3}/setup.cfg +0 -0
  151. {hgitaly-18.2.2 → hgitaly-18.2.3}/setup.py +0 -0
  152. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/__init__.py +0 -0
  153. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/comparison.py +0 -0
  154. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/conftest.py +0 -0
  155. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/gitaly.py +0 -0
  156. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/hgitaly_rhgitaly_comparison.py +0 -0
  157. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/rhgitaly.py +0 -0
  158. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_blob_tree.py +0 -0
  159. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_commit.py +0 -0
  160. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_comparison.py +0 -0
  161. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_diff.py +0 -0
  162. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_gitaly_server.py +0 -0
  163. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_mercurial_aux_git.py +0 -0
  164. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_mercurial_operations.py +0 -0
  165. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_mercurial_repository.py +0 -0
  166. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_ref.py +0 -0
  167. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_remote.py +0 -0
  168. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_repository_service.py +0 -0
  169. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_rhgitaly_server.py +0 -0
  170. {hgitaly-18.2.2 → hgitaly-18.2.3}/tests_with_gitaly/test_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hgitaly
3
- Version: 18.2.2
3
+ Version: 18.2.3
4
4
  Summary: Server-side implementation of Gitaly protocol for Mercurial
5
5
  Home-page: https://foss.heptapod.net/heptapod/hgitaly
6
6
  Author: Georges Racinet
@@ -0,0 +1 @@
1
+ 18.2.3
@@ -426,7 +426,9 @@ class OperationServicer(OperationServiceServicer, HGitalyServicer):
426
426
 
427
427
  if header.action in (ActionType.CREATE,
428
428
  ActionType.UPDATE):
429
- content_handler = UserCommitFilesContent(wd, header)
429
+ content_handler = UserCommitFilesContent(
430
+ context, wd, header
431
+ )
430
432
  else:
431
433
  content_handler = None
432
434
 
@@ -477,6 +479,31 @@ class OperationServicer(OperationServiceServicer, HGitalyServicer):
477
479
  )
478
480
 
479
481
 
482
+ def validate_checkout_path(context, relpath):
483
+ # absolute paths are interpreted by Gitaly as relative to the
484
+ # root of checkout.
485
+ relpath = relpath.lstrip(b'/')
486
+
487
+ for p in FORBIDDEN_IN_PATHS:
488
+ if p in relpath:
489
+ relpath_str = relpath.decode('utf-8', 'surrogateescape')
490
+
491
+ if p == DIRECTORY_CLIMB_UP:
492
+ # ill-named by upstream
493
+ error_type = 'ERROR_TYPE_DIRECTORY_TRAVERSAL'
494
+ msg = 'Path cannot include directory traversal'
495
+ else:
496
+ error_type = 'ERROR_TYPE_INVALID_PATH'
497
+ msg = f'invalid path: "{relpath_str}"'
498
+
499
+ index_error(context,
500
+ status_code='INVALID_ARGUMENT',
501
+ error_type=error_type,
502
+ msg=msg,
503
+ path=relpath)
504
+ return relpath
505
+
506
+
480
507
  class UserCommitFilesAction:
481
508
 
482
509
  def __init__(self, context, header, working_dir, changed_files):
@@ -485,9 +512,8 @@ class UserCommitFilesAction:
485
512
  self.changed_files = changed_files
486
513
 
487
514
  wd = self.working_dir = working_dir
488
- relpath = self.relpath = header.file_path
489
- self.validate(relpath)
490
- self.abspath = wd.file_path(relpath)
515
+ self.relpath = validate_checkout_path(context, header.file_path)
516
+ self.abspath = wd.file_path(self.relpath)
491
517
 
492
518
  def __call__(self):
493
519
  action = self.header.action
@@ -504,36 +530,6 @@ class UserCommitFilesAction:
504
530
  elif action == ActionType.CHMOD:
505
531
  return self.chmod()
506
532
 
507
- def validate(self, relpath):
508
- if os.path.isabs(relpath):
509
- index_error(
510
- self.context,
511
- status_code='INVALID_ARGUMENT',
512
- error_type='ERROR_TYPE_INVALID_PATH',
513
- msg='absolute',
514
- path=relpath,
515
- )
516
-
517
- for p in FORBIDDEN_IN_PATHS:
518
- if p in relpath:
519
- relpath_str = relpath.decode('utf-8', 'surrogateescape')
520
-
521
- if p == DIRECTORY_CLIMB_UP:
522
- # ill-named by upstream
523
- error_type = 'ERROR_TYPE_DIRECTORY_TRAVERSAL'
524
- msg = 'Path cannot include directory traversal'
525
- else:
526
- error_type = 'ERROR_TYPE_INVALID_PATH'
527
- msg = f'invalid path: "{relpath_str}"'
528
-
529
- index_error(
530
- self.context,
531
- status_code='INVALID_ARGUMENT',
532
- error_type=error_type,
533
- msg=msg,
534
- path=relpath,
535
- )
536
-
537
533
  def create(self):
538
534
  if os.path.exists(self.abspath):
539
535
  index_error(
@@ -600,8 +596,8 @@ class UserCommitFilesAction:
600
596
  def move(self):
601
597
  self.require_file_absence()
602
598
  abspath = self.abspath
603
- prev_relpath = self.header.previous_path
604
- self.validate(prev_relpath)
599
+ prev_relpath = validate_checkout_path(self.context,
600
+ self.header.previous_path)
605
601
  prev_abspath = self.working_dir.file_path(prev_relpath)
606
602
  self.require_file_existence(abspath=prev_abspath,
607
603
  relpath=prev_relpath)
@@ -636,8 +632,9 @@ class UserCommitFilesAction:
636
632
 
637
633
  class UserCommitFilesContent:
638
634
 
639
- def __init__(self, workdir, header):
640
- self.file_path = workdir.file_path(header.file_path)
635
+ def __init__(self, context, workdir, header):
636
+ relpath = validate_checkout_path(context, header.file_path)
637
+ self.file_path = workdir.file_path(relpath)
641
638
  self.fobj = open(self.file_path, 'wb')
642
639
  self.make_hg_executable = (header.action == ActionType.CREATE
643
640
  and header.execute_filemode)
@@ -757,7 +757,7 @@ def test_user_commit_files(operations_fixture, tmpdir):
757
757
  assert exc_info.value.code() == StatusCode.ALREADY_EXISTS
758
758
 
759
759
  # invalid paths
760
- for path in ('double//slash', '../../../good.joke', '/etc/shadow'):
760
+ for path in ('double//slash', '../../../good.joke'):
761
761
  with pytest.raises(RpcError) as exc_info:
762
762
  commit_files(
763
763
  branch_name=gl_branch,
@@ -793,6 +793,21 @@ def test_user_commit_files(operations_fixture, tmpdir):
793
793
  )
794
794
  assert exc_info.value.code() == StatusCode.INVALID_ARGUMENT
795
795
 
796
+ # leading slash is interpreted as meaning the root of checkout
797
+ resp = commit_files(
798
+ branch_name=gl_branch,
799
+ commit_message=b'Deleted intopic',
800
+ actions=(dict(action=ActionType.CREATE,
801
+ file_path=b'/etc/shadow',
802
+ content=b"This is in repo!",
803
+ ),
804
+ )
805
+ )
806
+ hex11 = resp.branch_update.commit_id.encode()
807
+ wrapper.reload()
808
+ clone_pull_update(hex11)
809
+ assert (clone.path / 'etc/shadow').read_binary() == b"This is in repo!"
810
+
796
811
  # bogus request flows
797
812
  header_req = fixture.user_commit_files_header(
798
813
  branch_name=gl_other_branch,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hgitaly
3
- Version: 18.2.2
3
+ Version: 18.2.3
4
4
  Summary: Server-side implementation of Gitaly protocol for Mercurial
5
5
  Home-page: https://foss.heptapod.net/heptapod/hgitaly
6
6
  Author: Georges Racinet
@@ -382,7 +382,7 @@ def test_compare_commit_files(comparison):
382
382
  branch_name=b'branch/default',
383
383
  tail_requests=ucf_actions(dict(
384
384
  action=ActionType.CREATE,
385
- file_path=b'foo',
385
+ file_path=b'/foo',
386
386
  content=b'foo content')),
387
387
  )
388
388
 
@@ -498,8 +498,7 @@ def test_compare_commit_files(comparison):
498
498
  ))
499
499
  )
500
500
 
501
- # invalid path (Gitaly does not reject absolute paths and actually
502
- # seems to ignore them, thankfully)
501
+ # invalid path
503
502
  for path in ('double//slash', '../../../good.joke'):
504
503
  for action in ('CREATE', 'CREATE_DIR', 'CHMOD',
505
504
  'UPDATE', 'DELETE', 'MOVE'):
@@ -1 +0,0 @@
1
- 18.2.2
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes