openSUSE / openSUSE/libsolv

repodata.add_dirstr() doesn't work with empty "dir", common to SRPM package "files"

Open
#397 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
609
Forks
177
PR merge metrics
No merged PRs in 30d

Description

This assertion: https://github.com/openSUSE/libsolv/blob/ac194e6f024420c0be72c49def6a80adc33dd4bf/src/repodata.c#L2929

Is problematic in the case of SRPMs, which frequently have files without directory. This means that dir is an empty string, which is converted to Id 0, which fails the assertion. Therefore parsing filelist data for a repository containing SRPMs or RPMs mixed with SRPMs will hit assertion failures unless action is taken externally to skip past the SRPM filelists.

See: standard RPMs have directory, SRPMs do not.

[dalley@localhost devel]$ rpm -qlp fzf-0.22.0-1.fc32.src.rpm
README.Fedora
fzf-0.22.0.tar.gz
fzf.spec

[dalley@localhost devel]$ rpm -qlp fzf-0.22.0-1.fc32.x86_64.rpm
/etc/bash_completion.d/fzf
/usr/bin/fzf
/usr/bin/fzf-tmux
...

This is the Python code being used to process file

    def rpm_filelist_conversion(solvable, unit):
        """A specific, rpm-unit-type filelist attribute conversion."""
        repodata = solv_repo.first_repodata()

        # file_repr = [None, '', 'test-srpm.spec']
        for file_repr in unit.get('files', []):
            dir_path = file_repr[1]    # empty string
            dirname_id = repodata.str2dir(dir_path)   # Id 0
            repodata.add_dirstr(
                solvable.id, solv.SOLVABLE_FILELIST,
                dirname_id, os.path.basename(dir_path)
            )
            # assertion failure: /tmp/pip-req-build-rneggjoc/src/repodata.c:2878: repodata_add_dirstr: Assertion `dir' failed.

The following patch successfully works around the problem and is good enough for us, but I'm curious whether there is a better way to solve it or if this is an unintentional oversight that should be fixed upstream.

         for file_repr in unit.get('files', []):
             dir_path = file_repr[1]
+            if not dir_path:
+                continue
             dirname_id = repodata.str2dir(dir_path)
             repodata.add_dirstr(

I have no idea if the methods for loading libsolv directly from repository XML are affected by this since we don't use them.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read src/repodata.c at the cited add_dirstr assertion and compare it with the Python rpm_filelist_conversion path shown in the report. Reproduce processing for an SRPM file with an empty directory, then verify that filelist handling no longer asserts while standard RPM file paths continue to work.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, python
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.