Coverage Report

Created: 2024-09-08 06:23

/src/git/protocol-caps.c
Line
Count
Source (jump to first uncovered line)
1
#include "git-compat-util.h"
2
#include "protocol-caps.h"
3
#include "gettext.h"
4
#include "hex.h"
5
#include "pkt-line.h"
6
#include "hash.h"
7
#include "hex.h"
8
#include "object.h"
9
#include "object-store-ll.h"
10
#include "repository.h"
11
#include "string-list.h"
12
#include "strbuf.h"
13
14
struct requested_info {
15
  unsigned size : 1;
16
};
17
18
/*
19
 * Parses oids from the given line and collects them in the given
20
 * oid_str_list. Returns 1 if parsing was successful and 0 otherwise.
21
 */
22
static int parse_oid(const char *line, struct string_list *oid_str_list)
23
0
{
24
0
  const char *arg;
25
26
0
  if (!skip_prefix(line, "oid ", &arg))
27
0
    return 0;
28
29
0
  string_list_append(oid_str_list, arg);
30
31
0
  return 1;
32
0
}
33
34
/*
35
 * Validates and send requested info back to the client. Any errors detected
36
 * are returned as they are detected.
37
 */
38
static void send_info(struct repository *r, struct packet_writer *writer,
39
          struct string_list *oid_str_list,
40
          struct requested_info *info)
41
0
{
42
0
  struct string_list_item *item;
43
0
  struct strbuf send_buffer = STRBUF_INIT;
44
45
0
  if (!oid_str_list->nr)
46
0
    return;
47
48
0
  if (info->size)
49
0
    packet_writer_write(writer, "size");
50
51
0
  for_each_string_list_item (item, oid_str_list) {
52
0
    const char *oid_str = item->string;
53
0
    struct object_id oid;
54
0
    unsigned long object_size;
55
56
0
    if (get_oid_hex_algop(oid_str, &oid, r->hash_algo) < 0) {
57
0
      packet_writer_error(
58
0
        writer,
59
0
        "object-info: protocol error, expected to get oid, not '%s'",
60
0
        oid_str);
61
0
      continue;
62
0
    }
63
64
0
    strbuf_addstr(&send_buffer, oid_str);
65
66
0
    if (info->size) {
67
0
      if (oid_object_info(r, &oid, &object_size) < 0) {
68
0
        strbuf_addstr(&send_buffer, " ");
69
0
      } else {
70
0
        strbuf_addf(&send_buffer, " %lu", object_size);
71
0
      }
72
0
    }
73
74
0
    packet_writer_write(writer, "%s", send_buffer.buf);
75
0
    strbuf_reset(&send_buffer);
76
0
  }
77
0
  strbuf_release(&send_buffer);
78
0
}
79
80
int cap_object_info(struct repository *r, struct packet_reader *request)
81
0
{
82
0
  struct requested_info info = { 0 };
83
0
  struct packet_writer writer;
84
0
  struct string_list oid_str_list = STRING_LIST_INIT_DUP;
85
86
0
  packet_writer_init(&writer, 1);
87
88
0
  while (packet_reader_read(request) == PACKET_READ_NORMAL) {
89
0
    if (!strcmp("size", request->line)) {
90
0
      info.size = 1;
91
0
      continue;
92
0
    }
93
94
0
    if (parse_oid(request->line, &oid_str_list))
95
0
      continue;
96
97
0
    packet_writer_error(&writer,
98
0
            "object-info: unexpected line: '%s'",
99
0
            request->line);
100
0
  }
101
102
0
  if (request->status != PACKET_READ_FLUSH) {
103
0
    packet_writer_error(
104
0
      &writer, "object-info: expected flush after arguments");
105
0
    die(_("object-info: expected flush after arguments"));
106
0
  }
107
108
0
  send_info(r, &writer, &oid_str_list, &info);
109
110
0
  string_list_clear(&oid_str_list, 1);
111
112
0
  packet_flush(1);
113
114
0
  return 0;
115
0
}