rugged 0.27.4 → 0.27.5

Sign up to get free protection for your applications and to get access to all the features.
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