Coverage Report

Created: 2024-09-08 06:24

/src/git/protocol.c
Line
Count
Source (jump to first uncovered line)
1
#define USE_THE_REPOSITORY_VARIABLE
2
3
#include "git-compat-util.h"
4
#include "config.h"
5
#include "environment.h"
6
#include "protocol.h"
7
#include "trace2.h"
8
9
static enum protocol_version parse_protocol_version(const char *value)
10
0
{
11
0
  if (!strcmp(value, "0"))
12
0
    return protocol_v0;
13
0
  else if (!strcmp(value, "1"))
14
0
    return protocol_v1;
15
0
  else if (!strcmp(value, "2"))
16
0
    return protocol_v2;
17
0
  else
18
0
    return protocol_unknown_version;
19
0
}
20
21
enum protocol_version get_protocol_version_config(void)
22
0
{
23
0
  const char *value;
24
0
  const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION";
25
0
  const char *git_test_v;
26
27
0
  if (!git_config_get_string_tmp("protocol.version", &value)) {
28
0
    enum protocol_version version = parse_protocol_version(value);
29
30
0
    if (version == protocol_unknown_version)
31
0
      die("unknown value for config 'protocol.version': %s",
32
0
          value);
33
34
0
    return version;
35
0
  }
36
37
0
  git_test_v = getenv(git_test_k);
38
0
  if (git_test_v && *git_test_v) {
39
0
    enum protocol_version env = parse_protocol_version(git_test_v);
40
41
0
    if (env == protocol_unknown_version)
42
0
      die("unknown value for %s: %s", git_test_k, git_test_v);
43
0
    return env;
44
0
  }
45
46
0
  return protocol_v2;
47
0
}
48
49
enum protocol_version determine_protocol_version_server(void)
50
0
{
51
0
  const char *git_protocol = getenv(GIT_PROTOCOL_ENVIRONMENT);
52
0
  enum protocol_version version = protocol_v0;
53
54
  /*
55
   * Determine which protocol version the client has requested.  Since
56
   * multiple 'version' keys can be sent by the client, indicating that
57
   * the client is okay to speak any of them, select the greatest version
58
   * that the client has requested.  This is due to the assumption that
59
   * the most recent protocol version will be the most state-of-the-art.
60
   */
61
0
  if (git_protocol) {
62
0
    struct string_list list = STRING_LIST_INIT_DUP;
63
0
    const struct string_list_item *item;
64
0
    string_list_split(&list, git_protocol, ':', -1);
65
66
0
    for_each_string_list_item(item, &list) {
67
0
      const char *value;
68
0
      enum protocol_version v;
69
70
0
      if (skip_prefix(item->string, "version=", &value)) {
71
0
        v = parse_protocol_version(value);
72
0
        if (v > version)
73
0
          version = v;
74
0
      }
75
0
    }
76
77
0
    string_list_clear(&list, 0);
78
0
  }
79
80
0
  trace2_data_intmax("transfer", NULL, "negotiated-version", version);
81
82
0
  return version;
83
0
}
84
85
enum protocol_version determine_protocol_version_client(const char *server_response)
86
0
{
87
0
  enum protocol_version version = protocol_v0;
88
89
0
  if (skip_prefix(server_response, "version ", &server_response)) {
90
0
    version = parse_protocol_version(server_response);
91
92
0
    if (version == protocol_unknown_version)
93
0
      die("server is speaking an unknown protocol");
94
0
    if (version == protocol_v0)
95
0
      die("protocol error: server explicitly said version 0");
96
0
  }
97
98
0
  return version;
99
0
}