Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect handling of torrent's params[b'announce-list'] and the trackers parameter of the /createtorrent endpoint #7825

Closed
kozlovsky opened this issue Jan 15, 2024 · 1 comment
Assignees

Comments

@kozlovsky
Copy link
Contributor

kozlovsky commented Jan 15, 2024

While reviewing #7816 I found an error in how the /createtorrent endpoint handles the tracker parameter.

The test_create_torrent test sends the following params to the endpoint:

    post_data = {
        "files": [str(torrent_path / "video.avi"),
                  str(torrent_path / "video.avi.torrent")],
        "description": "Video of my cat",
        "trackers": "http://localhost/announce",  # <-- !!!
        "name": "test_torrent",
        "export_dir": str(tmp_path)
    }
    response_dict = await do_request(rest_api, 'createtorrent?download=1', expected_code=200, request_type='POST',
                                     post_data=post_data)

That is, it sends "trackers" as a string, while it should be a list of string URLs. This fact is reflected in the Swagger API description of the endpoint:

    @docs(
        ...
    )
    @json_schema(schema(CreateTorrentRequest={
        'files': [String],
        'name': String,
        'description': String,
        'trackers': [String],  # <-- !!!
        'export_dir': String
    }))
    async def create_torrent(self, request):
        ...

You can see the 'trackers': [String] part of the endpoint description.

I expected that during the test run Swagger should catch the incorrect parameters, but it does not happen. It looks like something should be fixed about how Swagger is used in tests.

Anyway, this is how the trackers parameter is handled inside the endpoint:

        if 'trackers' in parameters and parameters['trackers']:
            tracker_url_list = parameters['trackers']
            params['announce'] = tracker_url_list[0]  # <-- !!!
            params['announce-list'] = tracker_url_list  # <-- !!!

So, the code expects that the value of parameters['trackers'] should be of list type. As the plain string "http://localhost/announce" is passed as a parameter, the resulted value of params['announce'] is "h", the first letter of the string. But then the parsed value is ignored by the test, so this error remained unnoticed.

So the first error is in test, as it passed an incorrect value to the endpoint.

Another error is in the endpoint itself, as params['announce-list'] should not be list, it should be of type List[List[str]], where each list represents a "tier" of trackers (on practice, there is usually only one tier). To thrigger the error it is necessary to pass a list of several tracker URLs, in this case the structure of the resulted params['announce-list'] is incorrect.

And the third bug is in the inner torrent_utils.create_torrent_file function that handles the created params:

    # main tracker
    if params.get(b'announce'):
        torrent.add_tracker(params[b'announce'])
    # tracker list
    if params.get(b'announce-list'):
        tier = 1
        for tracker in params[b'announce-list']:  # <-- !!!
            torrent.add_tracker(tracker, tier=tier)
            tier += 1

Here, the function incorrectly handles tracker tiers and assumes that params[b'announce-list'] contains list of strings, while in fact it should contain lists of lists of strings. The third error compensates for the second error, but probably not in all cases, as torrent_utils.create_torrent_file is also called from TorrentDef.save().

@kozlovsky kozlovsky self-assigned this Jan 15, 2024
@qstokkink
Copy link
Contributor

In the latest version of the Tribler code base, the libtorrent configuration dictionaries have type information. This should avoid any typing mismatches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants