static int
test_hex (void)
{
  char hex1[41];
  char hex2[41];
  uint8_t sha1[20];

  memcpy (hex1, "fb5ef5507427b17e04b69cef31fa3379b456735a", 41);
  tr_hex_to_sha1 (sha1, hex1);
  tr_sha1_to_hex (hex2, sha1);
  check_streq (hex1, hex2);

  return 0;
}
Example #2
0
tr_magnet_info *
tr_magnetParse( const char * uri )
{
    bool got_checksum = false;
    int trCount = 0;
    int wsCount = 0;
    char * tr[MAX_TRACKERS];
    char * ws[MAX_WEBSEEDS];
    char * displayName = NULL;
    uint8_t sha1[SHA_DIGEST_LENGTH];
    tr_magnet_info * info = NULL;

    if( ( uri != NULL ) && !memcmp( uri, "magnet:?", 8 ) )
    {
        const char * walk;

        for( walk=uri+8; walk && *walk; )
        {
            const char * key = walk;
            const char * delim = strchr( key, '=' );
            const char * val = delim == NULL ? NULL : delim + 1;
            const char * next = strchr( delim == NULL ? key : val, '&' );
            int keylen, vallen;

            if( delim != NULL )
                keylen = delim - key;
            else if( next != NULL )
                keylen = next - key;
            else
                keylen = strlen( key );

            if( val == NULL )
                vallen = 0;
            else if( next != NULL )
                vallen = next - val;
            else
                vallen = strlen( val );

            if( ( keylen==2 ) && !memcmp( key, "xt", 2 ) && val && !memcmp( val, "urn:btih:", 9 ) )
            {
                const char * hash = val + 9;
                const int hashlen = vallen - 9;

                if( hashlen == 40 ) {
                    tr_hex_to_sha1( sha1, hash );
                    got_checksum = true;
                }
                else if( hashlen == 32 ) {
                    base32_to_sha1( sha1, hash, hashlen );
                    got_checksum = true;
                }
            }

            if( ( vallen > 0 ) && ( keylen==2 ) && !memcmp( key, "dn", 2 ) )
                displayName = tr_http_unescape( val, vallen );

            if( ( vallen > 0 ) && ( trCount < MAX_TRACKERS ) ) {
                int i;
                if( ( keylen==2 ) && !memcmp( key, "tr", 2 ) )
                    tr[trCount++] = tr_http_unescape( val, vallen );
                else if( ( sscanf( key, "tr.%d=", &i ) == 1 ) && ( i > 0 ) ) /* ticket #3341 */
                    tr[trCount++] = tr_http_unescape( val, vallen );
            }

            if( ( vallen > 0 ) && ( keylen==2 ) && !memcmp( key, "ws", 2 ) && ( wsCount < MAX_WEBSEEDS ) )
                ws[wsCount++] = tr_http_unescape( val, vallen );

            walk = next != NULL ? next + 1 : NULL;
        }
    }

    if( got_checksum )
    {
        info = tr_new0( tr_magnet_info, 1 );
        info->displayName = displayName;
        info->trackerCount = trCount;
        info->trackers = tr_memdup( tr, sizeof(char*) * trCount );
        info->webseedCount = wsCount;
        info->webseeds = tr_memdup( ws, sizeof(char*) * wsCount );
        memcpy( info->hash, sha1, sizeof(uint8_t) * SHA_DIGEST_LENGTH );
    }

    return info;
}