rugged 0.26.6 → 0.26.7

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: 01c3a70759322be3a8b2360a27fada107c00228c5860ba9181c31c4e3c488e03
4
- data.tar.gz: 20b412c2167b6defcad204c73a2d33048a2278c2c613e82c709dac11f1fd8a07
3
+ metadata.gz: 4faf206e22374b400418a90f872b67e623ae2e3266e4fb3415eb44503af2f44c
4
+ data.tar.gz: 4e0f187f1256b99e1bbd9f52525dd21af71b964b7fdcedc6c718b0c8f4d0a619
5
5
  SHA512:
6
- metadata.gz: '029447faac7c0eac60dc87fcdb63f1a573a6909b56d23635f0c07c6f323b4a32062f9d600d421031451482a822c00fbe822f75fe86322f41179ce6698186a820'
7
- data.tar.gz: ae61df3ef7f009c9ab7fb86017a91fd93ce0320d354dc15344eb0077367fba514d7fbce0494704f9fa4fd1e159ad23a63a43eee6b7eac5bf83d505d65f2d3165
6
+ metadata.gz: 2803d2c5cf95a249b6d5ea2a36a5774243234bf96e0bf336e3a1e211eee3917a26a1c7d293019e63835ade97d8ec133275e3b8445dbebfc40d0b1fb439e2b86e
7
+ data.tar.gz: 59ba9779ad0090e8dd7ff369ae630e7fc1baf9f1c5de4ee89ec42bb5a9845f71cb485a7fd51a3f5a67f30c34793a94acf09193a77a541344c7143f225a7e7221
@@ -4,5 +4,5 @@
4
4
  # For full terms see the included LICENSE file.
5
5
 
6
6
  module Rugged
7
- Version = VERSION = '0.26.6'
7
+ Version = VERSION = '0.26.7'
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.26.6"
10
+ #define LIBGIT2_VERSION "0.26.7"
11
11
  #define LIBGIT2_VER_MAJOR 0
12
12
  #define LIBGIT2_VER_MINOR 26
13
- #define LIBGIT2_VER_REVISION 6
13
+ #define LIBGIT2_VER_REVISION 7
14
14
  #define LIBGIT2_VER_PATCH 0
15
15
 
16
16
  #define LIBGIT2_SOVERSION 26
@@ -1347,48 +1347,50 @@ done:
1347
1347
 
1348
1348
  static int parse_multiline_variable(struct reader *reader, git_buf *value, int in_quotes)
1349
1349
  {
1350
- char *line = NULL, *proc_line = NULL;
1351
1350
  int quote_count;
1352
- bool multiline;
1351
+ bool multiline = true;
1352
+
1353
+ while (multiline) {
1354
+ char *line = NULL, *proc_line = NULL;
1355
+ int error;
1356
+
1357
+ /* Check that the next line exists */
1358
+ line = reader_readline(reader, false);
1359
+ GITERR_CHECK_ALLOC(line);
1360
+
1361
+ /*
1362
+ * We've reached the end of the file, there is no continuation.
1363
+ * (this is not an error).
1364
+ */
1365
+ if (line[0] == '\0') {
1366
+ error = 0;
1367
+ goto out;
1368
+ }
1353
1369
 
1354
- /* Check that the next line exists */
1355
- line = reader_readline(reader, false);
1356
- if (line == NULL)
1357
- return -1;
1370
+ /* If it was just a comment, pretend it didn't exist */
1371
+ quote_count = strip_comments(line, !!in_quotes);
1372
+ if (line[0] == '\0')
1373
+ goto next;
1358
1374
 
1359
- /* We've reached the end of the file, there is no continuation.
1360
- * (this is not an error).
1361
- */
1362
- if (line[0] == '\0') {
1363
- git__free(line);
1364
- return 0;
1365
- }
1375
+ if ((error = unescape_line(&proc_line, &multiline,
1376
+ line, in_quotes)) < 0)
1377
+ goto out;
1366
1378
 
1367
- quote_count = strip_comments(line, !!in_quotes);
1379
+ /* Add this line to the multiline var */
1380
+ if ((error = git_buf_puts(value, proc_line)) < 0)
1381
+ goto out;
1368
1382
 
1369
- /* If it was just a comment, pretend it didn't exist */
1370
- if (line[0] == '\0') {
1383
+ next:
1371
1384
  git__free(line);
1372
- return parse_multiline_variable(reader, value, quote_count);
1373
- /* TODO: unbounded recursion. This **could** be exploitable */
1374
- }
1385
+ git__free(proc_line);
1386
+ in_quotes = quote_count;
1387
+ continue;
1375
1388
 
1376
- if (unescape_line(&proc_line, &multiline, line, in_quotes) < 0) {
1389
+ out:
1377
1390
  git__free(line);
1378
- return -1;
1391
+ git__free(proc_line);
1392
+ return error;
1379
1393
  }
1380
- /* add this line to the multiline var */
1381
-
1382
- git_buf_puts(value, proc_line);
1383
- git__free(line);
1384
- git__free(proc_line);
1385
-
1386
- /*
1387
- * If we need to continue reading the next line, let's just
1388
- * keep putting stuff in the buffer
1389
- */
1390
- if (multiline)
1391
- return parse_multiline_variable(reader, value, quote_count);
1392
1394
 
1393
1395
  return 0;
1394
1396
  }
@@ -1596,7 +1598,7 @@ static int read_on_variable(
1596
1598
  result = 0;
1597
1599
 
1598
1600
  /* Add or append the new config option */
1599
- if (!git__strcmp(var->entry->name, "include.path")) {
1601
+ if (!git__strcmp(var->entry->name, "include.path") && var->entry->value) {
1600
1602
  struct reader *r;
1601
1603
  git_buf path = GIT_BUF_INIT;
1602
1604
  char *dir;
@@ -209,7 +209,7 @@ static int packfile_load__cb(void *data, git_buf *path)
209
209
  for (i = 0; i < backend->packs.length; ++i) {
210
210
  struct git_pack_file *p = git_vector_get(&backend->packs, i);
211
211
 
212
- if (memcmp(p->pack_name, path_str, cmp_len) == 0)
212
+ if (strncmp(p->pack_name, path_str, cmp_len) == 0)
213
213
  return 0;
214
214
  }
215
215
 
@@ -1792,6 +1792,14 @@ static int get_value(const char **out, git_config *cfg, git_buf *buf, const char
1792
1792
  return error;
1793
1793
  }
1794
1794
 
1795
+ static bool looks_like_command_line_option(const char *s)
1796
+ {
1797
+ if (s && s[0] == '-')
1798
+ return true;
1799
+
1800
+ return false;
1801
+ }
1802
+
1795
1803
  static int submodule_read_config(git_submodule *sm, git_config *cfg)
1796
1804
  {
1797
1805
  git_buf key = GIT_BUF_INIT;
@@ -1805,24 +1813,31 @@ static int submodule_read_config(git_submodule *sm, git_config *cfg)
1805
1813
 
1806
1814
  if ((error = get_value(&value, cfg, &key, sm->name, "path")) == 0) {
1807
1815
  in_config = 1;
1816
+ /* We would warn here if we had that API */
1817
+ if (!looks_like_command_line_option(value)) {
1808
1818
  /*
1809
1819
  * TODO: if case insensitive filesystem, then the following strcmp
1810
1820
  * should be strcasecmp
1811
1821
  */
1812
- if (strcmp(sm->name, value) != 0) {
1813
- if (sm->path != sm->name)
1814
- git__free(sm->path);
1815
- sm->path = git__strdup(value);
1816
- GITERR_CHECK_ALLOC(sm->path);
1822
+ if (strcmp(sm->name, value) != 0) {
1823
+ if (sm->path != sm->name)
1824
+ git__free(sm->path);
1825
+ sm->path = git__strdup(value);
1826
+ GITERR_CHECK_ALLOC(sm->path);
1827
+ }
1828
+
1817
1829
  }
1818
1830
  } else if (error != GIT_ENOTFOUND) {
1819
1831
  goto cleanup;
1820
1832
  }
1821
1833
 
1822
1834
  if ((error = get_value(&value, cfg, &key, sm->name, "url")) == 0) {
1823
- in_config = 1;
1824
- sm->url = git__strdup(value);
1825
- GITERR_CHECK_ALLOC(sm->url);
1835
+ /* We would warn here if we had that API */
1836
+ if (!looks_like_command_line_option(value)) {
1837
+ in_config = 1;
1838
+ sm->url = git__strdup(value);
1839
+ GITERR_CHECK_ALLOC(sm->url);
1840
+ }
1826
1841
  } else if (error != GIT_ENOTFOUND) {
1827
1842
  goto cleanup;
1828
1843
  }
@@ -28,14 +28,14 @@
28
28
 
29
29
  extern bool git_smart__ofs_delta_enabled;
30
30
 
31
- enum git_pkt_type {
31
+ typedef enum {
32
32
  GIT_PKT_CMD,
33
33
  GIT_PKT_FLUSH,
34
34
  GIT_PKT_REF,
35
35
  GIT_PKT_HAVE,
36
36
  GIT_PKT_ACK,
37
37
  GIT_PKT_NAK,
38
- GIT_PKT_PACK,
38
+ GIT_PKT_PACK__UNUSED,
39
39
  GIT_PKT_COMMENT,
40
40
  GIT_PKT_ERR,
41
41
  GIT_PKT_DATA,
@@ -43,7 +43,7 @@ enum git_pkt_type {
43
43
  GIT_PKT_OK,
44
44
  GIT_PKT_NG,
45
45
  GIT_PKT_UNPACK,
46
- };
46
+ } git_pkt_type;
47
47
 
48
48
  /* Used for multi_ack and mutli_ack_detailed */
49
49
  enum git_ack_status {
@@ -55,11 +55,11 @@ enum git_ack_status {
55
55
 
56
56
  /* This would be a flush pkt */
57
57
  typedef struct {
58
- enum git_pkt_type type;
58
+ git_pkt_type type;
59
59
  } git_pkt;
60
60
 
61
61
  struct git_pkt_cmd {
62
- enum git_pkt_type type;
62
+ git_pkt_type type;
63
63
  char *cmd;
64
64
  char *path;
65
65
  char *host;
@@ -67,50 +67,50 @@ struct git_pkt_cmd {
67
67
 
68
68
  /* This is a pkt-line with some info in it */
69
69
  typedef struct {
70
- enum git_pkt_type type;
70
+ git_pkt_type type;
71
71
  git_remote_head head;
72
72
  char *capabilities;
73
73
  } git_pkt_ref;
74
74
 
75
75
  /* Useful later */
76
76
  typedef struct {
77
- enum git_pkt_type type;
77
+ git_pkt_type type;
78
78
  git_oid oid;
79
79
  enum git_ack_status status;
80
80
  } git_pkt_ack;
81
81
 
82
82
  typedef struct {
83
- enum git_pkt_type type;
83
+ git_pkt_type type;
84
84
  char comment[GIT_FLEX_ARRAY];
85
85
  } git_pkt_comment;
86
86
 
87
87
  typedef struct {
88
- enum git_pkt_type type;
89
- int len;
88
+ git_pkt_type type;
89
+ size_t len;
90
90
  char data[GIT_FLEX_ARRAY];
91
91
  } git_pkt_data;
92
92
 
93
93
  typedef git_pkt_data git_pkt_progress;
94
94
 
95
95
  typedef struct {
96
- enum git_pkt_type type;
97
- int len;
96
+ git_pkt_type type;
97
+ size_t len;
98
98
  char error[GIT_FLEX_ARRAY];
99
99
  } git_pkt_err;
100
100
 
101
101
  typedef struct {
102
- enum git_pkt_type type;
102
+ git_pkt_type type;
103
103
  char *ref;
104
104
  } git_pkt_ok;
105
105
 
106
106
  typedef struct {
107
- enum git_pkt_type type;
107
+ git_pkt_type type;
108
108
  char *ref;
109
109
  char *msg;
110
110
  } git_pkt_ng;
111
111
 
112
112
  typedef struct {
113
- enum git_pkt_type type;
113
+ git_pkt_type type;
114
114
  int unpack_ok;
115
115
  } git_pkt_unpack;
116
116
 
@@ -184,7 +184,7 @@ int git_smart__get_push_stream(transport_smart *t, git_smart_subtransport_stream
184
184
  int git_smart__update_heads(transport_smart *t, git_vector *symrefs);
185
185
 
186
186
  /* smart_pkt.c */
187
- int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
187
+ int git_pkt_parse_line(git_pkt **head, const char **endptr, const char *line, size_t linelen);
188
188
  int git_pkt_buffer_flush(git_buf *buf);
189
189
  int git_pkt_send_flush(GIT_SOCKET s);
190
190
  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)
@@ -41,7 +41,7 @@ int git_smart__store_refs(transport_smart *t, int flushes)
41
41
 
42
42
  do {
43
43
  if (buf->offset > 0)
44
- error = git_pkt_parse_line(&pkt, buf->data, &line_end, buf->offset);
44
+ error = git_pkt_parse_line(&pkt, &line_end, buf->data, buf->offset);
45
45
  else
46
46
  error = GIT_EBUFS;
47
47
 
@@ -206,15 +206,15 @@ int git_smart__detect_caps(git_pkt_ref *pkt, transport_smart_caps *caps, git_vec
206
206
  return 0;
207
207
  }
208
208
 
209
- static int recv_pkt(git_pkt **out, gitno_buffer *buf)
209
+ static int recv_pkt(git_pkt **out, git_pkt_type *pkt_type, gitno_buffer *buf)
210
210
  {
211
211
  const char *ptr = buf->data, *line_end = ptr;
212
212
  git_pkt *pkt = NULL;
213
- int pkt_type, error = 0, ret;
213
+ int error = 0, ret;
214
214
 
215
215
  do {
216
216
  if (buf->offset > 0)
217
- error = git_pkt_parse_line(&pkt, ptr, &line_end, buf->offset);
217
+ error = git_pkt_parse_line(&pkt, &line_end, ptr, buf->offset);
218
218
  else
219
219
  error = GIT_EBUFS;
220
220
 
@@ -233,13 +233,14 @@ static int recv_pkt(git_pkt **out, gitno_buffer *buf)
233
233
  } while (error);
234
234
 
235
235
  gitno_consume(buf, line_end);
236
- pkt_type = pkt->type;
236
+ if (pkt_type)
237
+ *pkt_type = pkt->type;
237
238
  if (out != NULL)
238
239
  *out = pkt;
239
240
  else
240
241
  git__free(pkt);
241
242
 
242
- return pkt_type;
243
+ return error;
243
244
  }
244
245
 
245
246
  static int store_common(transport_smart *t)
@@ -249,7 +250,7 @@ static int store_common(transport_smart *t)
249
250
  int error;
250
251
 
251
252
  do {
252
- if ((error = recv_pkt(&pkt, buf)) < 0)
253
+ if ((error = recv_pkt(&pkt, NULL, buf)) < 0)
253
254
  return error;
254
255
 
255
256
  if (pkt->type == GIT_PKT_ACK) {
@@ -317,7 +318,7 @@ static int wait_while_ack(gitno_buffer *buf)
317
318
  while (1) {
318
319
  git__free(pkt);
319
320
 
320
- if ((error = recv_pkt((git_pkt **)&pkt, buf)) < 0)
321
+ if ((error = recv_pkt((git_pkt **)&pkt, NULL, buf)) < 0)
321
322
  return error;
322
323
 
323
324
  if (pkt->type == GIT_PKT_NAK)
@@ -342,7 +343,8 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
342
343
  gitno_buffer *buf = &t->buffer;
343
344
  git_buf data = GIT_BUF_INIT;
344
345
  git_revwalk *walk = NULL;
345
- int error = -1, pkt_type;
346
+ int error = -1;
347
+ git_pkt_type pkt_type;
346
348
  unsigned int i;
347
349
  git_oid oid;
348
350
 
@@ -392,16 +394,13 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
392
394
  if ((error = store_common(t)) < 0)
393
395
  goto on_error;
394
396
  } else {
395
- pkt_type = recv_pkt(NULL, buf);
396
-
397
- if (pkt_type == GIT_PKT_ACK) {
397
+ error = recv_pkt(NULL, &pkt_type, buf);
398
+ if (error < 0) {
399
+ goto on_error;
400
+ } else if (pkt_type == GIT_PKT_ACK) {
398
401
  break;
399
402
  } else if (pkt_type == GIT_PKT_NAK) {
400
403
  continue;
401
- } else if (pkt_type < 0) {
402
- /* recv_pkt returned an error */
403
- error = pkt_type;
404
- goto on_error;
405
404
  } else {
406
405
  giterr_set(GITERR_NET, "Unexpected pkt type");
407
406
  error = -1;
@@ -467,10 +466,10 @@ int git_smart__negotiate_fetch(git_transport *transport, git_repository *repo, c
467
466
 
468
467
  /* Now let's eat up whatever the server gives us */
469
468
  if (!t->caps.multi_ack && !t->caps.multi_ack_detailed) {
470
- pkt_type = recv_pkt(NULL, buf);
469
+ error = recv_pkt(NULL, &pkt_type, buf);
471
470
 
472
- if (pkt_type < 0) {
473
- return pkt_type;
471
+ if (error < 0) {
472
+ return error;
474
473
  } else if (pkt_type != GIT_PKT_ACK && pkt_type != GIT_PKT_NAK) {
475
474
  giterr_set(GITERR_NET, "Unexpected pkt type");
476
475
  return -1;
@@ -591,7 +590,7 @@ int git_smart__download_pack(
591
590
  goto done;
592
591
  }
593
592
 
594
- if ((error = recv_pkt(&pkt, buf)) >= 0) {
593
+ if ((error = recv_pkt(&pkt, NULL, buf)) >= 0) {
595
594
  /* Check cancellation after network call */
596
595
  if (t->cancelled.val) {
597
596
  giterr_clear();
@@ -749,7 +748,7 @@ static int add_push_report_sideband_pkt(git_push *push, git_pkt_data *data_pkt,
749
748
  }
750
749
 
751
750
  while (line_len > 0) {
752
- error = git_pkt_parse_line(&pkt, line, &line_end, line_len);
751
+ error = git_pkt_parse_line(&pkt, &line_end, line, line_len);
753
752
 
754
753
  if (error == GIT_EBUFS) {
755
754
  /* Buffer the data when the inner packet is split
@@ -792,8 +791,8 @@ static int parse_report(transport_smart *transport, git_push *push)
792
791
 
793
792
  for (;;) {
794
793
  if (buf->offset > 0)
795
- error = git_pkt_parse_line(&pkt, buf->data,
796
- &line_end, buf->offset);
794
+ error = git_pkt_parse_line(&pkt, &line_end,
795
+ buf->data, buf->offset);
797
796
  else
798
797
  error = GIT_EBUFS;
799
798
 
@@ -250,35 +250,47 @@ void git__strtolower(char *str)
250
250
  git__strntolower(str, strlen(str));
251
251
  }
252
252
 
253
- int git__prefixcmp(const char *str, const char *prefix)
253
+ GIT_INLINE(int) prefixcmp(const char *str, size_t str_n, const char *prefix, bool icase)
254
254
  {
255
- for (;;) {
256
- unsigned char p = *(prefix++), s;
255
+ int s, p;
256
+
257
+ while (str_n--) {
258
+ s = (unsigned char)*str++;
259
+ p = (unsigned char)*prefix++;
260
+
261
+ if (icase) {
262
+ s = git__tolower(s);
263
+ p = git__tolower(p);
264
+ }
265
+
257
266
  if (!p)
258
267
  return 0;
259
- if ((s = *(str++)) != p)
268
+
269
+ if (s != p)
260
270
  return s - p;
261
271
  }
272
+
273
+ return (0 - *prefix);
262
274
  }
263
275
 
264
- int git__prefixcmp_icase(const char *str, const char *prefix)
276
+ int git__prefixcmp(const char *str, const char *prefix)
265
277
  {
266
- return strncasecmp(str, prefix, strlen(prefix));
278
+ return prefixcmp(str, SIZE_MAX, prefix, false);
267
279
  }
268
280
 
269
- int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix)
281
+ int git__prefixncmp(const char *str, size_t str_n, const char *prefix)
270
282
  {
271
- int s, p;
272
-
273
- while(str_n--) {
274
- s = (unsigned char)git__tolower(*str++);
275
- p = (unsigned char)git__tolower(*prefix++);
283
+ return prefixcmp(str, str_n, prefix, false);
284
+ }
276
285
 
277
- if (s != p)
278
- return s - p;
279
- }
286
+ int git__prefixcmp_icase(const char *str, const char *prefix)
287
+ {
288
+ return prefixcmp(str, SIZE_MAX, prefix, true);
289
+ }
280
290
 
281
- return (0 - *prefix);
291
+ int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix)
292
+ {
293
+ return prefixcmp(str, str_n, prefix, true);
282
294
  }
283
295
 
284
296
  int git__suffixcmp(const char *str, const char *suffix)
@@ -254,6 +254,7 @@ GIT_INLINE(void) git__free(void *ptr)
254
254
 
255
255
  extern int git__prefixcmp(const char *str, const char *prefix);
256
256
  extern int git__prefixcmp_icase(const char *str, const char *prefix);
257
+ extern int git__prefixncmp(const char *str, size_t str_n, const char *prefix);
257
258
  extern int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix);
258
259
  extern int git__suffixcmp(const char *str, const char *suffix);
259
260
 
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.26.6
4
+ version: 0.26.7
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-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler