Ticket #1254 (closed defect: fixed)

Opened 4 years ago

Last modified 4 years ago

Compillation error in xmlrpc.cc

Reported by: anonymous Owned by: rakshasa
Priority: normal Component: rtorrent
Version: Severity: major
Keywords: Cc:

Description

Unable to compile under Debian from svn: Linux acisco 2.6.8-3-686 #1 Tue Dec 5 21:26:38 UTC 2006 i686 GNU/Linux

xmlrpc.cc: In function 'rpc::target_type rpc::xmlrpc_to_target(xmlrpc_env*, xmlrpc_value*)':

xmlrpc.cc:213: error: jump to case label

xmlrpc.cc:156: error: crosses initialization of 'core::Download* download'

xmlrpc.cc: In function 'torrent::Object rpc::xmlrpc_to_object(xmlrpc_env*,

xmlrpc_value*, int, rpc::target_type*)':

xmlrpc.cc:284: warning: dereferencing type-punned pointer will break strict-aliasing rules

Change History

Changed 4 years ago by anonymous

I get the same error when configuring with "--with-xmlrpc-c" latest revision compiles fine for me without "--with-xmlrpc-c" parameter

Linux ubuntu7.10 2.6.22-14-server #1 SMP Tue Feb 12 08:27:05 UTC 2008 i686 GNU/Linux on an amd athlon 700.

Changed 4 years ago by anonymous

getting the same error on Centos 5.1

Changed 4 years ago by anonymous

Same error on debian lenny on NSLU2.

Changed 4 years ago by anonymous

is a fix going to be released? Can't test the new xmlrpc command or use xmlrpc at all.

Changed 4 years ago by anonymous

Libtorrent rev 1040 works fine with rtorrent 1039 :-) At least we have the DHT fix.

Changed 4 years ago by rakshasa

  • status changed from new to closed
  • resolution set to fixed

Changed 4 years ago by anonymous

  • status changed from closed to reopened
  • resolution fixed deleted

rtorrent rev 1040 doesn't work with libtorrent 1039 or 1040.

Changed 4 years ago by QBUS

The point is that defining variables inside case statement is not allowed without brackets. I've added "{" bracket just after the line "case XMLRPC_TYPE_STRING:" and "}" before default: return rpc::make_target(); and it started to compile (but don't know if this is good solution).

Part of file xmlrpc.cc afected by error after correction is:

// Consider making a helper function that creates a target_type from a
// torrent::Object, then we can just use xmlrpc_to_object.
rpc::target_type
xmlrpc_to_target(xmlrpc_env* env, xmlrpc_value* value) {
  rpc::target_type target;

  switch (xmlrpc_value_type(value)) {
  case XMLRPC_TYPE_STRING:
    {
    const char* str;
    xmlrpc_read_string(env, value, &str);

    if (env->fault_occurred)
      throw xmlrpc_error(env);

    if (std::strlen(str) == 0) {
      // When specifying void, we require a zero-length string.
      ::free((void*)str);
      return rpc::make_target();

    } else if (std::strlen(str) < 40) {
      ::free((void*)str);
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Unsupported target type found.");
    }

    core::Download* download = xmlrpc.get_slot_find_download()(str);

    if (download == NULL) {
      ::free((void*)str);
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Could not find info-hash.");
    }

    if (std::strlen(str) == 40) {
      ::free((void*)str);
      return rpc::make_target(download);
    }

    if (std::strlen(str) < 42 || str[40] != ':') {
      ::free((void*)str);
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Unsupported target type found.");
    }

    // Files:    "<hash>:f<index>"
    // Trackers: "<hash>:t<index>"

    int index;
    const char* end;

    switch (str[41]) {
    case 'f':
      end = str + 42;
      index = ::strtol(str + 42, (char**)&end, 0);

      if (*str == '\0' || *end != '\0')
        throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index.");

      target = rpc::make_target(XmlRpc::call_file, xmlrpc.get_slot_find_file()(download, index));
      break;
    case 't':
      end = str + 42;
      index = ::strtol(str + 42, (char**)&end, 0);

      if (*str == '\0' || *end != '\0')
        throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index.");

      target = rpc::make_target(XmlRpc::call_file, xmlrpc.get_slot_find_tracker()(download, index));
      break;

    default:
      ::free((void*)str);
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Unsupported target type found.");
    }

    ::free((void*)str);

    // Check if the target pointer is NULL.
    if (target.second == NULL)
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index.");

    return target;
        }
  default:
    return rpc::make_target();
  }
}

Changed 4 years ago by anonymous

thanks for the fix. It compiles and works fine now.

Changed 4 years ago by anonymous

I think declaring the variable at the top is better from a readability perspective :

// Consider making a helper function that creates a target_type from a
// torrent::Object, then we can just use xmlrpc_to_object.
rpc::target_type
xmlrpc_to_target(xmlrpc_env* env, xmlrpc_value* value) {
  rpc::target_type target;
  core::Download*  download;

  switch (xmlrpc_value_type(value)) {
  case XMLRPC_TYPE_STRING:
    const char* str;
    xmlrpc_read_string(env, value, &str);

    if (env->fault_occurred)
      throw xmlrpc_error(env);

    if (std::strlen(str) == 0) {
      // When specifying void, we require a zero-length string.
      ::free((void*)str);
      return rpc::make_target();

    } else if (std::strlen(str) < 40) {
      ::free((void*)str);
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Unsupported target type found.");
    }

    download = xmlrpc.get_slot_find_download()(str);

    if (download == NULL) {
      ::free((void*)str);
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Could not find info-hash.");
    }

    if (std::strlen(str) == 40) {
      ::free((void*)str);
      return rpc::make_target(download);
    }

    if (std::strlen(str) < 42 || str[40] != ':') {
      ::free((void*)str);
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Unsupported target type found.");
    }

    // Files:    "<hash>:f<index>"
    // Trackers: "<hash>:t<index>"

    int index;
    const char* end;

    switch (str[41]) {
    case 'f':
      end = str + 42;
      index = ::strtol(str + 42, (char**)&end, 0);

      if (*str == '\0' || *end != '\0')
        throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index.");

      target = rpc::make_target(XmlRpc::call_file, xmlrpc.get_slot_find_file()(download, index));
      break;

    case 't':
      end = str + 42;
      index = ::strtol(str + 42, (char**)&end, 0);

      if (*str == '\0' || *end != '\0')
        throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index.");

      target = rpc::make_target(XmlRpc::call_file, xmlrpc.get_slot_find_tracker()(download, index));
      break;

    default:
      ::free((void*)str);
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Unsupported target type found.");
    }

    ::free((void*)str);

    // Check if the target pointer is NULL.
    if (target.second == NULL)
      throw xmlrpc_error(XMLRPC_TYPE_ERROR, "Invalid index.");

    return target;

  default:
    return rpc::make_target();
  }
}

Changed 4 years ago by anonymous

The point is that defining variables inside case statement is not allowed without brackets. I've added "{" bracket just after the line "case XMLRPC_TYPE_STRING:" and "}" before default: return rpc::make_target(); and it started to compile (but don't know if this is good solution).

Part of file xmlrpc.cc afected by error after correction is:

it don`t help

Changed 4 years ago by rakshasa

  • status changed from reopened to closed
  • resolution set to fixed
Note: See TracTickets for help on using tickets.