Ticket #61 (closed defect)

Opened 9 years ago

Last modified 8 years ago

libssh2_scp_recv fails on large files

Reported by: stevenayre Owned by:
Priority: normal Milestone:
Component: Version:
Keywords: Cc: stevenayre, bagder
Blocked By: Blocks:

Description

I am trying to download a 2,719,984,337 byte (2.5 GB) file using scp_get in Net::SSH2, but it fails with the error "Invalid response from SCP server, invalid size" (LIBSSH2_ERROR_SCP_PROTOCOL).

Upon investigation, the problem lies in libssh2 490 of src/scp.c (in CVS):

session->scpRecv_size = strtol(p, &e, 10);

This returns a ERANGE error as 2,719,984,337 is more than the 2,147,483,647 limit of a signed integer.

Is there any way to get the library to support files larger than this limit? I'm guessing it'll be more involved than changing the data type to long long and using strtoll?

Change History

comment:1 Changed 9 years ago by anonymous

Logged In: NO

The following change fixed the problem for me:

--- libssh2-0.18.org/src/libssh2_priv.h 2008-02-27 18:43:08.000000000 +0100
+++ libssh2-0.18/src/libssh2_priv.h 2008-03-20 17:50:19.000000000 +0100
@@ -811,7 +811,7 @@

unsigned char scpRecv_response[LIBSSH2_SCP_RESPONSE_BUFLEN];
unsigned long scpRecv_response_len;
long scpRecv_mode;

  • long scpRecv_size;

+ off_t scpRecv_size;

long scpRecv_mtime;
long scpRecv_atime;
char *scpRecv_err_msg;

diff -ru libssh2-0.18.org/src/misc.c libssh2-0.18/src/misc.c
--- libssh2-0.18.org/src/misc.c 2008-02-27 18:43:10.000000000 +0100
+++ libssh2-0.18/src/misc.c 2008-03-20 18:37:33.000000000 +0100
@@ -62,7 +62,7 @@

msl = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
lsl = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];


  • return ((msl * 65536) * 65536) + lsl;

+ return ((msl * (libssh2_uint64_t) 65536) * 65536) + lsl;

}


/* }}} */

diff -ru libssh2-0.18.org/src/scp.c libssh2-0.18/src/scp.c
--- libssh2-0.18.org/src/scp.c 2008-02-27 18:43:27.000000000 +0100
+++ libssh2-0.18/src/scp.c 2008-03-20 17:51:26.000000000 +0100
@@ -487,7 +487,7 @@

*(s++) = '\0';
/* Make sure we don't get fooled by leftover values */
errno = 0;

  • session->scpRecv_size = strtol(p, &e, 10);

+ session->scpRecv_size = strtoull(p, &e, 10);

if ((e && *e)
errno) {

libssh2_error(session, LIBSSH2_ERROR_SCP_PROTOCOL,

"Invalid response from SCP server, invalid size",

@@ -513,7 +513,7 @@

goto scp_recv_error;

}
_libssh2_debug(session, LIBSSH2_DBG_SCP,

  • "mode = 0%lo size = %ld", session->scpRecv_mode,

+ "mode = 0%lo size = %lld", session->scpRecv_mode,

session->scpRecv_size);


/* We *should* check that basename is valid, but why let that stop us? */

Additionally the library needs to get compiled with largefile support enabled, e.g. by adding the output of the command "getconf LFS_CFLAGS" to CFLAGS, "getconf LFS_LDFLAGS" to LDFLAGS, and "getconf LFS_LIBS" to LIBS, respectively.

This causes the type "off_t" to be either 32 or 64 bit, as required on the target platform.

comment:2 Changed 8 years ago by bagder

I based a fix on your patch and committed it just now. Please get the latest code and see if it works for you!

comment:3 Changed 8 years ago by sf-robot

This Tracker item was closed automatically by the system. It was
previously set to a Pending status, and the original submitter
did not respond within 14 days (the time period specified by
the administrator of this Tracker).

Note: See TracTickets for help on using tickets.