effect of handling it, but they do not free it if it isn't a packet
they recognise as part of their upload/download. Invent a return value
that specifically signals this, and consistently free pktin at every
call site if that return value comes back. Also, ensure that that
return value also always comes with something meaningful in fxp_error.
git-svn-id: svn://svn.tartarus.org/sgt/putty@9915
cda61777-01e9-0310-a592-
d414129be87e
ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
if (ret <= 0) {
tell_user(stderr, "error while writing: %s", fxp_error());
ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
if (ret <= 0) {
tell_user(stderr, "error while writing: %s", fxp_error());
+ if (ret == INT_MIN) /* pktin not even freed */
+ sfree(pktin);
ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
if (ret <= 0) {
tell_user(stderr, "error while writing: %s", fxp_error());
ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
if (ret <= 0) {
tell_user(stderr, "error while writing: %s", fxp_error());
+ if (ret == INT_MIN) /* pktin not even freed */
+ sfree(pktin);
ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
if (ret <= 0) {
tell_user(stderr, "pscp: error while reading: %s", fxp_error());
ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
if (ret <= 0) {
tell_user(stderr, "pscp: error while reading: %s", fxp_error());
+ if (ret == INT_MIN) /* pktin not even freed */
+ sfree(pktin);
ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
if (ret <= 0) {
tell_user(stderr, "pscp: error while reading: %s", fxp_error());
ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
if (ret <= 0) {
tell_user(stderr, "pscp: error while reading: %s", fxp_error());
+ if (ret == INT_MIN) /* pktin not even freed */
+ sfree(pktin);
printf("error while reading: %s\n", fxp_error());
shown_err = TRUE;
}
printf("error while reading: %s\n", fxp_error());
shown_err = TRUE;
}
+ if (ret == INT_MIN) /* pktin not even freed */
+ sfree(pktin);
if (!xfer_done(xfer)) {
pktin = sftp_recv();
ret = xfer_upload_gotpkt(xfer, pktin);
if (!xfer_done(xfer)) {
pktin = sftp_recv();
ret = xfer_upload_gotpkt(xfer, pktin);
- if (ret <= 0 && !err) {
- printf("error while writing: %s\n", fxp_error());
- err = 1;
+ if (ret <= 0) {
+ if (ret == INT_MIN) /* pktin not even freed */
+ sfree(pktin);
+ if (!err) {
+ printf("error while writing: %s\n", fxp_error());
+ err = 1;
+ }
+/*
+ * Returns INT_MIN to indicate that it didn't even get as far as
+ * fxp_read_recv and hence has not freed pktin.
+ */
int xfer_download_gotpkt(struct fxp_xfer *xfer, struct sftp_packet *pktin)
{
struct sftp_request *rreq;
int xfer_download_gotpkt(struct fxp_xfer *xfer, struct sftp_packet *pktin)
{
struct sftp_request *rreq;
rreq = sftp_find_request(pktin);
if (!rreq)
rreq = sftp_find_request(pktin);
if (!rreq)
- return 0; /* this packet doesn't even make sense */
+ return INT_MIN; /* this packet doesn't even make sense */
rr = (struct req *)fxp_get_userdata(rreq);
rr = (struct req *)fxp_get_userdata(rreq);
- if (!rr)
- return 0; /* this packet isn't ours */
+ if (!rr) {
+ fxp_internal_error("request ID is not part of the current download");
+ return INT_MIN; /* this packet isn't ours */
+ }
rr->retlen = fxp_read_recv(pktin, rreq, rr->buffer, rr->len);
#ifdef DEBUG_DOWNLOAD
printf("read request %p has returned [%d]\n", rr, rr->retlen);
rr->retlen = fxp_read_recv(pktin, rreq, rr->buffer, rr->len);
#ifdef DEBUG_DOWNLOAD
printf("read request %p has returned [%d]\n", rr, rr->retlen);
+/*
+ * Returns INT_MIN to indicate that it didn't even get as far as
+ * fxp_write_recv and hence has not freed pktin.
+ */
int xfer_upload_gotpkt(struct fxp_xfer *xfer, struct sftp_packet *pktin)
{
struct sftp_request *rreq;
int xfer_upload_gotpkt(struct fxp_xfer *xfer, struct sftp_packet *pktin)
{
struct sftp_request *rreq;
rreq = sftp_find_request(pktin);
if (!rreq)
rreq = sftp_find_request(pktin);
if (!rreq)
- return 0; /* this packet doesn't even make sense */
+ return INT_MIN; /* this packet doesn't even make sense */
rr = (struct req *)fxp_get_userdata(rreq);
rr = (struct req *)fxp_get_userdata(rreq);
- if (!rr)
- return 0; /* this packet isn't ours */
+ if (!rr) {
+ fxp_internal_error("request ID is not part of the current upload");
+ return INT_MIN; /* this packet isn't ours */
+ }
ret = fxp_write_recv(pktin, rreq);
#ifdef DEBUG_UPLOAD
printf("write request %p has returned [%d]\n", rr, ret);
ret = fxp_write_recv(pktin, rreq);
#ifdef DEBUG_UPLOAD
printf("write request %p has returned [%d]\n", rr, ret);