rugged 0.27.4 → 0.27.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 075b5f14d04691ea47a585c8295f594f8db17e555401d0c34afdc1b9ee998c79
4
- data.tar.gz: 2d38ebeef1721dbcf676e00a32471f664d8d71702a7871f6a7cf9551c1929f65
3
+ metadata.gz: 38cf39184ada925f1c17a76c4b9c23390f10e983360a2383243cf01e915c0352
4
+ data.tar.gz: 76e02389e381e6efca72089dce787260bdb6b869f7fb201c3c1f5000d6f3453b
5
5
  SHA512:
6
- metadata.gz: 126a5c098f1dc094234795d8f26f4049272fdc6823e3e89a7e93afa2b6ac0583624183a0e730845e47ddfc318a3a209caac2b9af624ccce77c4e72f8ff50b8fd
7
- data.tar.gz: 68c08ff84c4fcf0d55d8656148c605159c7582abae8f669220601e795928e571a569ddc90b7a31d1ffac31be91c19b8b8dabc41d1be5ffc51d197f1c80381c1c
6
+ metadata.gz: 2332a9d8d33f3b873ccd9de0949185589925ea22449d79ccc7c03230e54216beaf99032420dad85086e313f5d5225739b26f322392fb1370e66c3c1e3f8e4487
7
+ data.tar.gz: a8748762ade17561d1548da2c90bbc02e9da4bf1703a4e984d678dd6944fc1feff74e51f9921d016e7c3abc2f413e6bc07bda798feea04a5d1b549eb78869030
@@ -4,5 +4,5 @@
4
4
  # For full terms see the included LICENSE file.
5
5
 
6
6
  module Rugged
7
- Version = VERSION = '0.27.4'
7
+ Version = VERSION = '0.27.5'
8
8
  end
@@ -7,10 +7,10 @@
7
7
  #ifndef INCLUDE_git_version_h__
8
8
  #define INCLUDE_git_version_h__
9
9
 
10
- #define LIBGIT2_VERSION "0.27.4"
10
+ #define LIBGIT2_VERSION "0.27.5"
11
11
  #define LIBGIT2_VER_MAJOR 0
12
12
  #define LIBGIT2_VER_MINOR 27
13
- #define LIBGIT2_VER_REVISION 4
13
+ #define LIBGIT2_VER_REVISION 5
14
14
  #define LIBGIT2_VER_PATCH 0
15
15
 
16
16
  #define LIBGIT2_SOVERSION 27
@@ -928,6 +928,9 @@ static int parse_include(git_config_parser *reader,
928
928
  char *dir;
929
929
  int result;
930
930
 
931
+ if (!file)
932
+ return 0;
933
+
931
934
  if ((result = git_path_dirname_r(&path, reader->file->path)) < 0)
932
935
  return result;
933
936
 
@@ -1029,7 +1032,7 @@ static int parse_conditional_include(git_config_parser *reader,
1029
1032
  size_t i;
1030
1033
  int error = 0, matches;
1031
1034
 
1032
- if (!parse_data->repo)
1035
+ if (!parse_data->repo || !file)
1033
1036
  return 0;
1034
1037
 
1035
1038
  condition = git__substrdup(section + strlen("includeIf."),
@@ -315,49 +315,51 @@ done:
315
315
 
316
316
  static int parse_multiline_variable(git_config_parser *reader, git_buf *value, int in_quotes)
317
317
  {
318
- char *line = NULL, *proc_line = NULL;
319
318
  int quote_count;
320
- bool multiline;
319
+ bool multiline = true;
321
320
 
322
- /* Check that the next line exists */
323
- git_parse_advance_line(&reader->ctx);
324
- line = git__strndup(reader->ctx.line, reader->ctx.line_len);
325
- if (line == NULL)
326
- return -1;
321
+ while (multiline) {
322
+ char *line = NULL, *proc_line = NULL;
323
+ int error;
327
324
 
328
- /* We've reached the end of the file, there is no continuation.
329
- * (this is not an error).
330
- */
331
- if (line[0] == '\0') {
332
- git__free(line);
333
- return 0;
334
- }
325
+ /* Check that the next line exists */
326
+ git_parse_advance_line(&reader->ctx);
327
+ line = git__strndup(reader->ctx.line, reader->ctx.line_len);
328
+ GITERR_CHECK_ALLOC(line);
329
+
330
+ /*
331
+ * We've reached the end of the file, there is no continuation.
332
+ * (this is not an error).
333
+ */
334
+ if (line[0] == '\0') {
335
+ error = 0;
336
+ goto out;
337
+ }
335
338
 
336
- quote_count = strip_comments(line, !!in_quotes);
339
+ /* If it was just a comment, pretend it didn't exist */
340
+ quote_count = strip_comments(line, !!in_quotes);
341
+ if (line[0] == '\0')
342
+ goto next;
337
343
 
338
- /* If it was just a comment, pretend it didn't exist */
339
- if (line[0] == '\0') {
344
+ if ((error = unescape_line(&proc_line, &multiline,
345
+ line, in_quotes)) < 0)
346
+ goto out;
347
+
348
+ /* Add this line to the multiline var */
349
+ if ((error = git_buf_puts(value, proc_line)) < 0)
350
+ goto out;
351
+
352
+ next:
340
353
  git__free(line);
341
- return parse_multiline_variable(reader, value, quote_count);
342
- /* TODO: unbounded recursion. This **could** be exploitable */
343
- }
354
+ git__free(proc_line);
355
+ in_quotes = quote_count;
356
+ continue;
344
357
 
345
- if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
358
+ out:
346
359
  git__free(line);
347
- return -1;
360
+ git__free(proc_line);
361
+ return error;
348
362
  }
349
- /* add this line to the multiline var */
350
-
351
- git_buf_puts(value, proc_line);
352
- git__free(line);
353
- git__free(proc_line);
354
-
355
- /*
356
- * If we need to continue reading the next line, let's just
357
- * keep putting stuff in the buffer
358
- */
359
- if (multiline)
360
- return parse_multiline_variable(reader, value, quote_count);
361
363
 
362
364
  return 0;
363
365
  }
@@ -210,7 +210,7 @@ static int packfile_load__cb(void *data, git_buf *path)
210
210
  for (i = 0; i < backend->packs.length; ++i) {
211
211
  struct git_pack_file *p = git_vector_get(&backend->packs, i);
212
212
 
213
- if (memcmp(p->pack_name, path_str, cmp_len) == 0)
213
+ if (strncmp(p->pack_name, path_str, cmp_len) == 0)
214
214
  return 0;
215
215
  }
216
216
 
@@ -1813,6 +1813,14 @@ static int get_value(const char **out, git_config *cfg, git_buf *buf, const char
1813
1813
  return error;
1814
1814
  }
1815
1815
 
1816
+ static bool looks_like_command_line_option(const char *s)
1817
+ {
1818
+ if (s && s[0] == '-')
1819
+ return true;
1820
+
1821
+ return false;
1822
+ }
1823
+
1816
1824
  static int submodule_read_config(git_submodule *sm, git_config *cfg)
1817
1825
  {
1818
1826
  git_buf key = GIT_BUF_INIT;
@@ -1826,24 +1834,31 @@ static int submodule_read_config(git_submodule *sm, git_config *cfg)
1826
1834
 
1827
1835
  if ((error = get_value(&value, cfg, &key, sm->name, "path")) == 0) {
1828
1836
  in_config = 1;
1837
+ /* We would warn here if we had that API */
1838
+ if (!looks_like_command_line_option(value)) {
1829
1839
  /*
1830
1840
  * TODO: if case insensitive filesystem, then the following strcmp
1831
1841
  * should be strcasecmp
1832
1842
  */
1833
- if (strcmp(sm->name, value) != 0) {
1834
- if (sm->path != sm->name)
1835
- git__free(sm->path);
1836
- sm->path = git__strdup(value);
1837
- GITERR_CHECK_ALLOC(sm->path);
1843
+ if (strcmp(sm->name, value) != 0) {
1844
+ if (sm->path != sm->name)
1845
+ git__free(sm->path);
1846
+ sm->path = git__strdup(value);
1847
+ GITERR_CHECK_ALLOC(sm->path);
1848
+ }
1849
+
1838
1850
  }
1839
1851
  } else if (error != GIT_ENOTFOUND) {
1840
1852
  goto cleanup;
1841
1853
  }
1842
1854
 
1843
1855
  if ((error = get_value(&value, cfg, &key, sm->name, "url")) == 0) {
1844
- in_config = 1;
1845
- sm->url = git__strdup(value);
1846
- GITERR_CHECK_ALLOC(sm->url);
1856
+ /* We would warn here if we had that API */
1857
+ if (!looks_like_command_line_option(value)) {
1858
+ in_config = 1;
1859
+ sm->url = git__strdup(value);
1860
+ GITERR_CHECK_ALLOC(sm->url);
1861
+ }
1847
1862
  } else if (error != GIT_ENOTFOUND) {
1848
1863
  goto cleanup;
1849
1864
  }
@@ -33,14 +33,14 @@
33
33
 
34
34
  extern bool git_smart__ofs_delta_enabled;
35
35
 
36
- enum git_pkt_type {
36
+ typedef enum {
37
37
  GIT_PKT_CMD,
38
38
  GIT_PKT_FLUSH,
39
39
  GIT_PKT_REF,
40
40
  GIT_PKT_HAVE,
41
41
  GIT_PKT_ACK,
42
42
  GIT_PKT_NAK,
43
- GIT_PKT_PACK,
43
+ GIT_PKT_PACK__UNUSED,
44
44
  GIT_PKT_COMMENT,
45
45
  GIT_PKT_ERR,
46
46
  GIT_PKT_DATA,
@@ -48,7 +48,7 @@ enum git_pkt_type {
48
48
  GIT_PKT_OK,
49
49
  GIT_PKT_NG,
50
50
  GIT_PKT_UNPACK,
51
- };
51
+ } git_pkt_type;
52
52
 
53
53
  /* Used for multi_ack and mutli_ack_detailed */
54
54
  enum git_ack_status {
@@ -60,11 +60,11 @@ enum git_ack_status {
60
60
 
61
61
  /* This would be a flush pkt */
62
62
  typedef struct {
63
- enum git_pkt_type type;
63
+ git_pkt_type type;
64
64
  } git_pkt;
65
65
 
66
66
  struct git_pkt_cmd {
67
- enum git_pkt_type type;
67
+ git_pkt_type type;
68
68
  char *cmd;
69
69
  char *path;
70
70
  char *host;
@@ -72,50 +72,50 @@ struct git_pkt_cmd {
72
72
 
73
73
  /* This is a pkt-line with some info in it */
74
74
  typedef struct {
75
- enum git_pkt_type type;
75
+ git_pkt_type type;
76
76
  git_remote_head head;
77
77
  char *capabilities;
78
78
  } git_pkt_ref;
79
79
 
80
80
  /* Useful later */
81
81
  typedef struct {
82
- enum git_pkt_type type;
82
+ git_pkt_type type;
83
83
  git_oid oid;
84
84
  enum git_ack_status status;
85
85
  } git_pkt_ack;
86
86
 
87
87
  typedef struct {
88
- enum git_pkt_type type;
88
+ git_pkt_type type;
89
89
  char comment[GIT_FLEX_ARRAY];
90
90
  } git_pkt_comment;
91
91
 
92
92
  typedef struct {
93
- enum git_pkt_type type;
94
- int len;
93
+ git_pkt_type type;
94
+ size_t len;
95
95
  char data[GIT_FLEX_ARRAY];
96
96
  } git_pkt_data;
97
97
 
98
98
  typedef git_pkt_data git_pkt_progress;
99
99
 
100
100
  typedef struct {
101
- enum git_pkt_type type;
102
- int len;
101
+ git_pkt_type type;
102
+ size_t len;
103
103
  char error[GIT_FLEX_ARRAY];
104
104
  } git_pkt_err;
105
105
 
106
106
  typedef struct {
107
- enum git_pkt_type type;
107
+ git_pkt_type type;
108
108
  char *ref;
109
109
  } git_pkt_ok;
110
110
 
111
111
  typedef struct {
112
- enum git_pkt_type type;
112
+ git_pkt_type type;
113
113
  char *ref;
114
114
  char *msg;
115
115
  } git_pkt_ng;
116
116
 
117
117
  typedef struct {
118
- enum git_pkt_type type;
118
+ git_pkt_type type;
119
119
  int unpack_ok;
120
120
  } git_pkt_unpack;
121
121
 
@@ -189,7 +189,7 @@ int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream
189
189
  int git_smart__update_heads(transport_smart *t, git_vector *symrefs);
190
190
 
191
191
  /* smart_pkt.c */
192
- int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
192
+ int git_pkt_parse_line(git_pkt **head, const char **endptr, const char *line, size_t linelen);
193
193
  int git_pkt_buffer_flush(git_buf *buf);
194
194
  int git_pkt_send_flush(GIT_SOCKET s);
195
195
  int git_pkt_buffer_done(git_buf *buf);
@@ -43,34 +43,43 @@ static int flush_pkt(git_pkt **out)
43
43
  static int ack_pkt(git_pkt **out, const char *line, size_t len)
44
44
  {
45
45
  git_pkt_ack *pkt;
46
- GIT_UNUSED(line);
47
- GIT_UNUSED(len);
48
46
 
49
47
  pkt = git__calloc(1, sizeof(git_pkt_ack));
50
48
  GITERR_CHECK_ALLOC(pkt);
51
-
52
49
  pkt->type = GIT_PKT_ACK;
53
- line += 3;
54
- len -= 3;
55
50
 
56
- if (len >= GIT_OID_HEXSZ) {
57
- git_oid_fromstr(&pkt->oid, line + 1);
58
- line += GIT_OID_HEXSZ + 1;
59
- len -= GIT_OID_HEXSZ + 1;
60
- }
51
+ if (git__prefixncmp(line, len, "ACK "))
52
+ goto out_err;
53
+ line += 4;
54
+ len -= 4;
55
+
56
+ if (len < GIT_OID_HEXSZ || git_oid_fromstr(&pkt->oid, line) < 0)
57
+ goto out_err;
58
+ line += GIT_OID_HEXSZ;
59
+ len -= GIT_OID_HEXSZ;
61
60
 
62
- if (len >= 7) {
63
- if (!git__prefixcmp(line + 1, "continue"))
61
+ if (len && line[0] == ' ') {
62
+ line++;
63
+ len--;
64
+
65
+ if (!git__prefixncmp(line, len, "continue"))
64
66
  pkt->status = GIT_ACK_CONTINUE;
65
- if (!git__prefixcmp(line + 1, "common"))
67
+ else if (!git__prefixncmp(line, len, "common"))
66
68
  pkt->status = GIT_ACK_COMMON;
67
- if (!git__prefixcmp(line + 1, "ready"))
69
+ else if (!git__prefixncmp(line, len, "ready"))
68
70
  pkt->status = GIT_ACK_READY;
71
+ else
72
+ goto out_err;
69
73
  }
70
74
 
71
75
  *out = (git_pkt *) pkt;
72
76
 
73
77
  return 0;
78
+
79
+ out_err:
80
+ giterr_set(GITERR_NET, "error parsing ACK pkt-line");
81
+ git__free(pkt);
82
+ return -1;
74
83
  }
75
84
 
76
85
  static int nak_pkt(git_pkt **out)
@@ -86,19 +95,6 @@ static int nak_pkt(git_pkt **out)
86
95
  return 0;
87
96
  }
88
97
 
89
- static int pack_pkt(git_pkt **out)
90
- {
91
- git_pkt *pkt;
92
-
93
- pkt = git__malloc(sizeof(git_pkt));
94
- GITERR_CHECK_ALLOC(pkt);
95
-
96
- pkt->type = GIT_PKT_PACK;
97
- *out = pkt;
98
-
99
- return 0;
100
- }
101
-
102
98
  static int comment_pkt(git_pkt **out, const char *line, size_t len)
103
99
  {
104
100
  git_pkt_comment *pkt;
@@ -120,10 +116,12 @@ static int comment_pkt(git_pkt **out, const char *line, size_t len)
120
116
 
121
117
  static int err_pkt(git_pkt **out, const char *line, size_t len)
122
118
  {
123
- git_pkt_err *pkt;
119
+ git_pkt_err *pkt = NULL;
124
120
  size_t alloclen;
125
121
 
126
122
  /* Remove "ERR " from the line */
123
+ if (git__prefixncmp(line, len, "ERR "))
124
+ goto out_err;
127
125
  line += 4;
128
126
  len -= 4;
129
127
 
@@ -131,15 +129,20 @@ static int err_pkt(git_pkt **out, const char *line, size_t len)
131
129
  GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
132
130
  pkt = git__malloc(alloclen);
133
131
  GITERR_CHECK_ALLOC(pkt);
134
-
135
132
  pkt->type = GIT_PKT_ERR;
136
- pkt->len = (int)len;
133
+ pkt->len = len;
134
+
137
135
  memcpy(pkt->error, line, len);
138
136
  pkt->error[len] = '\0';
139
137
 
140
138
  *out = (git_pkt *) pkt;
141
139
 
142
140
  return 0;
141
+
142
+ out_err:
143
+ giterr_set(GITERR_NET, "error parsing ERR pkt-line");
144
+ git__free(pkt);
145
+ return -1;
143
146
  }
144
147
 
145
148
  static int data_pkt(git_pkt **out, const char *line, size_t len)
@@ -155,7 +158,7 @@ static int data_pkt(git_pkt **out, const char *line, size_t len)
155
158
  GITERR_CHECK_ALLOC(pkt);
156
159
 
157
160
  pkt->type = GIT_PKT_DATA;
158
- pkt->len = (int) len;
161
+ pkt->len = len;
159
162
  memcpy(pkt->data, line, len);
160
163
 
161
164
  *out = (git_pkt *) pkt;
@@ -176,7 +179,7 @@ static int sideband_progress_pkt(git_pkt **out, const char *line, size_t len)
176
179
  GITERR_CHECK_ALLOC(pkt);
177
180
 
178
181
  pkt->type = GIT_PKT_PROGRESS;
179
- pkt->len = (int) len;
182
+ pkt->len = len;
180
183
  memcpy(pkt->data, line, len);
181
184
 
182
185
  *out = (git_pkt *) pkt;
@@ -212,28 +215,25 @@ static int sideband_error_pkt(git_pkt **out, const char *line, size_t len)
212
215
  */
213
216
  static int ref_pkt(git_pkt **out, const char *line, size_t len)
214
217
  {
215
- int error;
216
218
  git_pkt_ref *pkt;
217
219
  size_t alloclen;
218
220
 
219
- pkt = git__malloc(sizeof(git_pkt_ref));
221
+ pkt = git__calloc(1, sizeof(git_pkt_ref));
220
222
  GITERR_CHECK_ALLOC(pkt);
221
-
222
- memset(pkt, 0x0, sizeof(git_pkt_ref));
223
223
  pkt->type = GIT_PKT_REF;
224
- if ((error = git_oid_fromstr(&pkt->head.oid, line)) < 0)
225
- goto error_out;
226
-
227
- /* Check for a bit of consistency */
228
- if (line[GIT_OID_HEXSZ] != ' ') {
229
- giterr_set(GITERR_NET, "error parsing pkt-line");
230
- error = -1;
231
- goto error_out;
232
- }
233
224
 
234
- /* Jump from the name */
235
- line += GIT_OID_HEXSZ + 1;
236
- len -= (GIT_OID_HEXSZ + 1);
225
+ if (len < GIT_OID_HEXSZ || git_oid_fromstr(&pkt->head.oid, line) < 0)
226
+ goto out_err;
227
+ line += GIT_OID_HEXSZ;
228
+ len -= GIT_OID_HEXSZ;
229
+
230
+ if (git__prefixncmp(line, len, " "))
231
+ goto out_err;
232
+ line++;
233
+ len--;
234
+
235
+ if (!len)
236
+ goto out_err;
237
237
 
238
238
  if (line[len - 1] == '\n')
239
239
  --len;
@@ -245,36 +245,36 @@ static int ref_pkt(git_pkt **out, const char *line, size_t len)
245
245
  memcpy(pkt->head.name, line, len);
246
246
  pkt->head.name[len] = '\0';
247
247
 
248
- if (strlen(pkt->head.name) < len) {
248
+ if (strlen(pkt->head.name) < len)
249
249
  pkt->capabilities = strchr(pkt->head.name, '\0') + 1;
250
- }
251
250
 
252
251
  *out = (git_pkt *)pkt;
253
252
  return 0;
254
253
 
255
- error_out:
254
+ out_err:
255
+ giterr_set(GITERR_NET, "error parsing REF pkt-line");
256
+ if (pkt)
257
+ git__free(pkt->head.name);
256
258
  git__free(pkt);
257
- return error;
259
+ return -1;
258
260
  }
259
261
 
260
262
  static int ok_pkt(git_pkt **out, const char *line, size_t len)
261
263
  {
262
264
  git_pkt_ok *pkt;
263
- const char *ptr;
264
265
  size_t alloc_len;
265
266
 
266
267
  pkt = git__malloc(sizeof(*pkt));
267
268
  GITERR_CHECK_ALLOC(pkt);
268
-
269
269
  pkt->type = GIT_PKT_OK;
270
270
 
271
- line += 3; /* skip "ok " */
272
- if (!(ptr = strchr(line, '\n'))) {
273
- giterr_set(GITERR_NET, "invalid packet line");
274
- git__free(pkt);
275
- return -1;
276
- }
277
- len = ptr - line;
271
+ if (git__prefixncmp(line, len, "ok "))
272
+ goto out_err;
273
+ line += 3;
274
+ len -= 3;
275
+
276
+ if (line[len - 1] == '\n')
277
+ --len;
278
278
 
279
279
  GITERR_CHECK_ALLOC_ADD(&alloc_len, len, 1);
280
280
  pkt->ref = git__malloc(alloc_len);
@@ -285,12 +285,17 @@ static int ok_pkt(git_pkt **out, const char *line, size_t len)
285
285
 
286
286
  *out = (git_pkt *)pkt;
287
287
  return 0;
288
+
289
+ out_err:
290
+ giterr_set(GITERR_NET, "error parsing OK pkt-line");
291
+ git__free(pkt);
292
+ return -1;
288
293
  }
289
294
 
290
295
  static int ng_pkt(git_pkt **out, const char *line, size_t len)
291
296
  {
292
297
  git_pkt_ng *pkt;
293
- const char *ptr;
298
+ const char *ptr, *eol;
294
299
  size_t alloclen;
295
300
 
296
301
  pkt = git__malloc(sizeof(*pkt));
@@ -299,11 +304,13 @@ static int ng_pkt(git_pkt **out, const char *line, size_t len)
299
304
  pkt->ref = NULL;
300
305
  pkt->type = GIT_PKT_NG;
301
306
 
302
- if (len < 3)
307
+ eol = line + len;
308
+
309
+ if (git__prefixncmp(line, len, "ng "))
303
310
  goto out_err;
304
- line += 3; /* skip "ng " */
305
- len -= 3;
306
- if (!(ptr = memchr(line, ' ', len)))
311
+ line += 3;
312
+
313
+ if (!(ptr = memchr(line, ' ', eol - line)))
307
314
  goto out_err;
308
315
  len = ptr - line;
309
316
 
@@ -314,11 +321,11 @@ static int ng_pkt(git_pkt **out, const char *line, size_t len)
314
321
  memcpy(pkt->ref, line, len);
315
322
  pkt->ref[len] = '\0';
316
323
 
317
- if (len < 1)
318
- goto out_err;
319
324
  line = ptr + 1;
320
- len -= 1;
321
- if (!(ptr = memchr(line, '\n', len)))
325
+ if (line >= eol)
326
+ goto out_err;
327
+
328
+ if (!(ptr = memchr(line, '\n', eol - line)))
322
329
  goto out_err;
323
330
  len = ptr - line;
324
331
 
@@ -343,13 +350,11 @@ static int unpack_pkt(git_pkt **out, const char *line, size_t len)
343
350
  {
344
351
  git_pkt_unpack *pkt;
345
352
 
346
- GIT_UNUSED(len);
347
-
348
353
  pkt = git__malloc(sizeof(*pkt));
349
354
  GITERR_CHECK_ALLOC(pkt);
350
-
351
355
  pkt->type = GIT_PKT_UNPACK;
352
- if (!git__prefixcmp(line, "unpack ok"))
356
+
357
+ if (!git__prefixncmp(line, len, "unpack ok"))
353
358
  pkt->unpack_ok = 1;
354
359
  else
355
360
  pkt->unpack_ok = 0;
@@ -358,13 +363,17 @@ static int unpack_pkt(git_pkt **out, const char *line, size_t len)
358
363
  return 0;
359
364
  }
360
365
 
361
- static int32_t parse_len(const char *line)
366
+ static int parse_len(size_t *out, const char *line, size_t linelen)
362
367
  {
363
368
  char num[PKT_LEN_SIZE + 1];
364
369
  int i, k, error;
365
370
  int32_t len;
366
371
  const char *num_end;
367
372
 
373
+ /* Not even enough for the length */
374
+ if (linelen < PKT_LEN_SIZE)
375
+ return GIT_EBUFS;
376
+
368
377
  memcpy(num, line, PKT_LEN_SIZE);
369
378
  num[PKT_LEN_SIZE] = '\0';
370
379
 
@@ -376,7 +385,7 @@ static int32_t parse_len(const char *line)
376
385
  num[k] = '.';
377
386
  }
378
387
  }
379
-
388
+
380
389
  giterr_set(GITERR_NET, "invalid hex digit in length: '%s'", num);
381
390
  return -1;
382
391
  }
@@ -385,7 +394,11 @@ static int32_t parse_len(const char *line)
385
394
  if ((error = git__strtol32(&len, num, &num_end, 16)) < 0)
386
395
  return error;
387
396
 
388
- return len;
397
+ if (len < 0)
398
+ return -1;
399
+
400
+ *out = (size_t) len;
401
+ return 0;
389
402
  }
390
403
 
391
404
  /*
@@ -402,35 +415,32 @@ static int32_t parse_len(const char *line)
402
415
  */
403
416
 
404
417
  int git_pkt_parse_line(
405
- git_pkt **head, const char *line, const char **out, size_t bufflen)
418
+ git_pkt **pkt, const char **endptr, const char *line, size_t linelen)
406
419
  {
407
- int ret;
408
- int32_t len;
409
-
410
- /* Not even enough for the length */
411
- if (bufflen > 0 && bufflen < PKT_LEN_SIZE)
412
- return GIT_EBUFS;
420
+ int error;
421
+ size_t len;
413
422
 
414
- len = parse_len(line);
415
- if (len < 0) {
423
+ if ((error = parse_len(&len, line, linelen)) < 0) {
416
424
  /*
417
- * If we fail to parse the length, it might be because the
418
- * server is trying to send us the packfile already.
425
+ * If we fail to parse the length, it might be
426
+ * because the server is trying to send us the
427
+ * packfile already or because we do not yet have
428
+ * enough data.
419
429
  */
420
- if (bufflen >= 4 && !git__prefixcmp(line, "PACK")) {
421
- giterr_clear();
422
- *out = line;
423
- return pack_pkt(head);
424
- }
425
-
426
- return (int)len;
430
+ if (error == GIT_EBUFS)
431
+ ;
432
+ else if (!git__prefixncmp(line, linelen, "PACK"))
433
+ giterr_set(GITERR_NET, "unexpected pack file");
434
+ else
435
+ giterr_set(GITERR_NET, "bad packet length");
436
+ return error;
427
437
  }
428
438
 
429
439
  /*
430
- * If we were given a buffer length, then make sure there is
431
- * enough in the buffer to satisfy this line
440
+ * Make sure there is enough in the buffer to satisfy
441
+ * this line.
432
442
  */
433
- if (bufflen > 0 && bufflen < (size_t)len)
443
+ if (linelen < len)
434
444
  return GIT_EBUFS;
435
445
 
436
446
  /*
@@ -453,38 +463,38 @@ int git_pkt_parse_line(
453
463
  }
454
464
 
455
465
  if (len == 0) { /* Flush pkt */
456
- *out = line;
457
- return flush_pkt(head);
466
+ *endptr = line;
467
+ return flush_pkt(pkt);
458
468
  }
459
469
 
460
470
  len -= PKT_LEN_SIZE; /* the encoded length includes its own size */
461
471
 
462
472
  if (*line == GIT_SIDE_BAND_DATA)
463
- ret = data_pkt(head, line, len);
473
+ error = data_pkt(pkt, line, len);
464
474
  else if (*line == GIT_SIDE_BAND_PROGRESS)
465
- ret = sideband_progress_pkt(head, line, len);
475
+ error = sideband_progress_pkt(pkt, line, len);
466
476
  else if (*line == GIT_SIDE_BAND_ERROR)
467
- ret = sideband_error_pkt(head, line, len);
468
- else if (!git__prefixcmp(line, "ACK"))
469
- ret = ack_pkt(head, line, len);
470
- else if (!git__prefixcmp(line, "NAK"))
471
- ret = nak_pkt(head);
472
- else if (!git__prefixcmp(line, "ERR "))
473
- ret = err_pkt(head, line, len);
477
+ error = sideband_error_pkt(pkt, line, len);
478
+ else if (!git__prefixncmp(line, len, "ACK"))
479
+ error = ack_pkt(pkt, line, len);
480
+ else if (!git__prefixncmp(line, len, "NAK"))
481
+ error = nak_pkt(pkt);
482
+ else if (!git__prefixncmp(line, len, "ERR"))
483
+ error = err_pkt(pkt, line, len);
474
484
  else if (*line == '#')
475
- ret = comment_pkt(head, line, len);
476
- else if (!git__prefixcmp(line, "ok"))
477
- ret = ok_pkt(head, line, len);
478
- else if (!git__prefixcmp(line, "ng"))
479
- ret = ng_pkt(head, line, len);
480
- else if (!git__prefixcmp(line, "unpack"))
481
- ret = unpack_pkt(head, line, len);
485
+ error = comment_pkt(pkt, line, len);
486
+ else if (!git__prefixncmp(line, len, "ok"))
487
+ error = ok_pkt(pkt, line, len);
488
+ else if (!git__prefixncmp(line, len, "ng"))
489
+ error = ng_pkt(pkt, line, len);
490
+ else if (!git__prefixncmp(line, len, "unpack"))
491
+ error = unpack_pkt(pkt, line, len);
482
492
  else
483
- ret = ref_pkt(head, line, len);
493
+ error = ref_pkt(pkt, line, len);
484
494
 
485
- *out = line + len;
495
+ *endptr = line + len;
486
496
 
487
- return ret;
497
+ return error;
488
498
  }
489
499
 
490
500
  void git_pkt_free(git_pkt *pkt)
@@ -44,7 +44,7 @@ int git_smart__store_refs(transport_smart *t, int flushes)
44
44
 
45
45
  do {
46
46
  if (buf->offset > 0)
47
- error = git_pkt_parse_line(&pkt, buf->data, &line_end, buf->offset);
47
+ error = git_pkt_parse_line(&pkt, &line_end, buf->data, buf->offset);
48
48
  else
49
49
  error = GIT_EBUFS;
50
50
 
@@ -209,15 +209,15 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec
209
209
  return 0;
210
210
  }
211
211
 
212
- static int recv_pkt(git_pkt **out, gitno_buffer *buf)
212
+ static int recv_pkt(git_pkt **out, git_pkt_type *pkt_type, gitno_buffer *buf)
213
213
  {
214
214
  const char *ptr = buf->data, *line_end = ptr;
215
215
  git_pkt *pkt = NULL;
216
- int pkt_type, error = 0, ret;
216
+ int error = 0, ret;
217
217
 
218
218
  do {
219
219
  if (buf->offset > 0)
220
- error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->offset);
220
+ error = git_pkt_parse_line(&pkt, &line_end, ptr, buf->offset);
221
221
  else
222
222
  error = GIT_EBUFS;
223
223
 
@@ -236,13 +236,14 @@ static int recv_pkt(git_pkt **out, gitno_buffer *buf)
236
236
  } while (error);
237
237
 
238
238
  gitno_consume(buf, line_end);
239
- pkt_type = pkt->type;
239
+ if (pkt_type)
240
+ *pkt_type = pkt->type;
240
241
  if (out != NULL)
241
242
  *out = pkt;
242
243
  else
243
244
  git__free(pkt);
244
245
 
245
- return pkt_type;
246
+ return error;
246
247
  }
247
248
 
248
249
  static int store_common(transport_smart *t)
@@ -252,7 +253,7 @@ static int store_common(transport_smart *t)
252
253
  int error;
253
254
 
254
255
  do {
255
- if ((error = recv_pkt(&pkt, buf)) < 0)
256
+ if ((error = recv_pkt(&pkt, NULL, buf)) < 0)
256
257
  return error;
257
258
 
258
259
  if (pkt->type == GIT_PKT_ACK) {
@@ -320,7 +321,7 @@ static int wait_while_ack(gitno_buffer *buf)
320
321
  while (1) {
321
322
  git__free(pkt);
322
323
 
323
- if ((error = recv_pkt((git_pkt **)&pkt, buf)) < 0)
324
+ if ((error = recv_pkt((git_pkt **)&pkt, NULL, buf)) < 0)
324
325
  return error;
325
326
 
326
327
  if (pkt->type == GIT_PKT_NAK)
@@ -345,7 +346,8 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
345
346
  gitno_buffer *buf = &t->buffer;
346
347
  git_buf data = GIT_BUF_INIT;
347
348
  git_revwalk *walk = NULL;
348
- int error = -1, pkt_type;
349
+ int error = -1;
350
+ git_pkt_type pkt_type;
349
351
  unsigned int i;
350
352
  git_oid oid;
351
353
 
@@ -395,16 +397,13 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
395
397
  if ((error = store_common(t)) < 0)
396
398
  goto on_error;
397
399
  } else {
398
- pkt_type = recv_pkt(NULL, buf);
399
-
400
- if (pkt_type == GIT_PKT_ACK) {
400
+ error = recv_pkt(NULL, &pkt_type, buf);
401
+ if (error < 0) {
402
+ goto on_error;
403
+ } else if (pkt_type == GIT_PKT_ACK) {
401
404
  break;
402
405
  } else if (pkt_type == GIT_PKT_NAK) {
403
406
  continue;
404
- } else if (pkt_type < 0) {
405
- /* recv_pkt returned an error */
406
- error = pkt_type;
407
- goto on_error;
408
407
  } else {
409
408
  giterr_set(GITERR_NET, "Unexpected pkt type");
410
409
  error = -1;
@@ -470,10 +469,10 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
470
469
 
471
470
  /* Now let's eat up whatever the server gives us */
472
471
  if (!t->caps.multi_ack && !t->caps.multi_ack_detailed) {
473
- pkt_type = recv_pkt(NULL, buf);
472
+ error = recv_pkt(NULL, &pkt_type, buf);
474
473
 
475
- if (pkt_type < 0) {
476
- return pkt_type;
474
+ if (error < 0) {
475
+ return error;
477
476
  } else if (pkt_type != GIT_PKT_ACK && pkt_type != GIT_PKT_NAK) {
478
477
  giterr_set(GITERR_NET, "Unexpected pkt type");
479
478
  return -1;
@@ -594,7 +593,7 @@ int git_smart__download_pack(
594
593
  goto done;
595
594
  }
596
595
 
597
- if ((error = recv_pkt(&pkt, buf)) >= 0) {
596
+ if ((error = recv_pkt(&pkt, NULL, buf)) >= 0) {
598
597
  /* Check cancellation after network call */
599
598
  if (t->cancelled.val) {
600
599
  giterr_clear();
@@ -752,7 +751,7 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt,
752
751
  }
753
752
 
754
753
  while (line_len > 0) {
755
- error = git_pkt_parse_line(&pkt, line, &line_end, line_len);
754
+ error = git_pkt_parse_line(&pkt, &line_end, line, line_len);
756
755
 
757
756
  if (error == GIT_EBUFS) {
758
757
  /* Buffer the data when the inner packet is split
@@ -795,8 +794,8 @@ static int parse_report(transport_smart *transport, git_push *push)
795
794
 
796
795
  for (;;) {
797
796
  if (buf->offset > 0)
798
- error = git_pkt_parse_line(&pkt, buf->data,
799
- &line_end, buf->offset);
797
+ error = git_pkt_parse_line(&pkt, &line_end,
798
+ buf->data, buf->offset);
800
799
  else
801
800
  error = GIT_EBUFS;
802
801
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rugged
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.27.4
4
+ version: 0.27.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Chacon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-08-08 00:00:00.000000000 Z
12
+ date: 2018-10-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler