rugged 0.26.6 → 0.26.7

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: 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