Skip to content

Commit b0e3e2d

Browse files
peffdscho
authored andcommitted
http: prefer CURLOPT_SEEKFUNCTION to CURLOPT_IOCTLFUNCTION
The IOCTLFUNCTION option has been deprecated, and generates a compiler warning in recent versions of curl. We can switch to using SEEKFUNCTION instead. It was added in 2008 via curl 7.18.0; our INSTALL file already indicates we require at least curl 7.19.4. But there's one catch: curl says we should use CURL_SEEKFUNC_{OK,FAIL}, and those didn't arrive until 7.19.5. One workaround would be to use a bare 0/1 here (or define our own macros). But let's just bump the minimum required version to 7.19.5. That version is only a minor version bump from our existing requirement, and is only a 2 month time bump for versions that are almost 13 years old. So it's not likely that anybody cares about the distinction. Switching means we have to rewrite the ioctl functions into seek functions. In some ways they are simpler (seeking is the only operation), but in some ways more complex (the ioctl allowed only a full rewind, but now we can seek to arbitrary offsets). Curl will only ever use SEEK_SET (per their documentation), so I didn't bother implementing anything else, since it would naturally be completely untested. This seems unlikely to change, but I added an assertion just in case. Likewise, I doubt curl will ever try to seek outside of the buffer sizes we've told it, but I erred on the defensive side here, rather than do an out-of-bounds read. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]>
1 parent fda237c commit b0e3e2d

File tree

5 files changed

+36
-36
lines changed

5 files changed

+36
-36
lines changed

INSTALL

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ Issues of note:
145145
patches into an IMAP mailbox, you do not have to have them
146146
(use NO_CURL).
147147

148+
Git requires version "7.19.5" or later of "libcurl" to build
149+
without NO_CURL. This version requirement may be bumped in
150+
the future.
151+
148152
- "expat" library; git-http-push uses it for remote lock
149153
management over DAV. Similar to "curl" above, this is optional
150154
(with NO_EXPAT).

http-push.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,9 @@ static void curl_setup_http(CURL *curl, const char *url,
203203
curl_easy_setopt(curl, CURLOPT_INFILE, buffer);
204204
curl_easy_setopt(curl, CURLOPT_INFILESIZE, buffer->buf.len);
205205
curl_easy_setopt(curl, CURLOPT_READFUNCTION, fread_buffer);
206-
#ifndef NO_CURL_IOCTL
207-
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_buffer);
208-
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, buffer);
206+
#ifndef NO_CURL_SEEK
207+
curl_easy_setopt(curl, CURLOPT_SEEKFUNCTION, seek_buffer);
208+
curl_easy_setopt(curl, CURLOPT_SEEKDATA, buffer);
209209
#endif
210210
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_fn);
211211
curl_easy_setopt(curl, CURLOPT_NOBODY, 0);

http.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -186,22 +186,20 @@ size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *buffer_)
186186
return size / eltsize;
187187
}
188188

189-
#ifndef NO_CURL_IOCTL
190-
curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp)
189+
#ifndef NO_CURL_SEEK
190+
int seek_buffer(void *clientp, curl_off_t offset, int origin)
191191
{
192192
struct buffer *buffer = clientp;
193193

194-
switch (cmd) {
195-
case CURLIOCMD_NOP:
196-
return CURLIOE_OK;
197-
198-
case CURLIOCMD_RESTARTREAD:
199-
buffer->posn = 0;
200-
return CURLIOE_OK;
201-
202-
default:
203-
return CURLIOE_UNKNOWNCMD;
194+
if (origin != SEEK_SET)
195+
BUG("seek_buffer only handles SEEK_SET");
196+
if (offset < 0 || offset >= buffer->buf.len) {
197+
error("curl seek would be outside of buffer");
198+
return CURL_SEEKFUNC_FAIL;
204199
}
200+
201+
buffer->posn = offset;
202+
return CURL_SEEKFUNC_OK;
205203
}
206204
#endif
207205

http.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
#define CURLE_HTTP_RETURNED_ERROR CURLE_HTTP_NOT_FOUND
4242
#endif
4343

44-
#if LIBCURL_VERSION_NUM < 0x070c03
45-
#define NO_CURL_IOCTL
44+
#if LIBCURL_VERSION_NUM < 0x071200
45+
#define NO_CURL_SEEK
4646
#endif
4747

4848
/*
@@ -82,8 +82,8 @@ struct buffer {
8282
size_t fread_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
8383
size_t fwrite_buffer(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
8484
size_t fwrite_null(char *ptr, size_t eltsize, size_t nmemb, void *strbuf);
85-
#ifndef NO_CURL_IOCTL
86-
curlioerr ioctl_buffer(CURL *handle, int cmd, void *clientp);
85+
#ifndef NO_CURL_SEEK
86+
int seek_buffer(void *clientp, curl_off_t offset, int origin);
8787
#endif
8888

8989
/* Slot lifecycle functions */

remote-curl.c

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -707,26 +707,24 @@ static size_t rpc_out(void *ptr, size_t eltsize,
707707
return avail;
708708
}
709709

710-
#ifndef NO_CURL_IOCTL
711-
static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)
710+
#ifndef NO_CURL_SEEK
711+
static int rpc_seek(void *clientp, curl_off_t offset, int origin)
712712
{
713713
struct rpc_state *rpc = clientp;
714714

715-
switch (cmd) {
716-
case CURLIOCMD_NOP:
717-
return CURLIOE_OK;
715+
if (origin != SEEK_SET)
716+
BUG("rpc_seek only handles SEEK_SET, not %d", origin);
718717

719-
case CURLIOCMD_RESTARTREAD:
720-
if (rpc->initial_buffer) {
721-
rpc->pos = 0;
722-
return CURLIOE_OK;
718+
if (rpc->initial_buffer) {
719+
if (offset < 0 || offset > rpc->len) {
720+
error("curl seek would be outside of rpc buffer");
721+
return CURL_SEEKFUNC_FAIL;
723722
}
724-
error(_("unable to rewind rpc post data - try increasing http.postBuffer"));
725-
return CURLIOE_FAILRESTART;
726-
727-
default:
728-
return CURLIOE_UNKNOWNCMD;
723+
rpc->pos = offset;
724+
return CURL_SEEKFUNC_OK;
729725
}
726+
error(_("unable to rewind rpc post data - try increasing http.postBuffer"));
727+
return CURL_SEEKFUNC_FAIL;
730728
}
731729
#endif
732730

@@ -947,9 +945,9 @@ static int post_rpc(struct rpc_state *rpc, int stateless_connect, int flush_rece
947945
rpc->initial_buffer = 1;
948946
curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);
949947
curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);
950-
#ifndef NO_CURL_IOCTL
951-
curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);
952-
curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);
948+
#ifndef NO_CURL_SEEK
949+
curl_easy_setopt(slot->curl, CURLOPT_SEEKFUNCTION, rpc_seek);
950+
curl_easy_setopt(slot->curl, CURLOPT_SEEKDATA, rpc);
953951
#endif
954952
if (options.verbosity > 1) {
955953
fprintf(stderr, "POST %s (chunked)\n", rpc->service_name);

0 commit comments

Comments
 (0)