mvdan / fdroidcl

F-Droid desktop client
BSD 3-Clause "New" or "Revised" License
269 stars 22 forks source link

Nil pointer dereference on upgrading APK version that is missing in the repo #7

Closed relan closed 8 years ago

relan commented 8 years ago

I'm on the latest master:

$ fdroidcl upgrade org.gnu.icecat
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x10 pc=0x40c5c0]

goroutine 1 [running]:
main.runUpgrade(0xc82000a440, 0x1, 0x1)
    /home/xxx/golang/src/github.com/mvdan/fdroidcl/cmd/fdroidcl/upgrade.go:37 +0x470
main.main()
    /home/xxx/golang/src/github.com/mvdan/fdroidcl/cmd/fdroidcl/main.go:180 +0x416

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/lib/golang/src/runtime/asm_amd64.s:1721 +0x1

I have IceCat 38.6 installed on my device while F-Droid repository contains only 38.7.1.

fdroidcl crashes here:

func runUpgrade(args []string) {
    ...
    for _, app := range apps {
        p, e := inst[app.ID]
        ...
        cur := app.CurApk() // <<< returns nil
        if p.VCode >= cur.VCode { // <<< crash here
            log.Fatalf("%s is up to date", app.ID)
        }
    }
    ...
}

As far as I understand, runUpgrade() tries to find current APK among APKs in the repo. This is not always the case, e.g. when APK has been moved to the archive and user tries to upgrade it after that.

I known that I won't be able to upgrade IceCat anyway due to #5. This issue is about upgrading APKs missing in the repo to the versions that are in the repo.

mvdan commented 8 years ago

You seem to have dived into the codebase - have you tried to patch the bug? :)

relan commented 8 years ago

I can more or less read Go code due to its similarity to other C-like languages, but I'll have to learn it to write the code.

mvdan commented 8 years ago

No worries. Just wanted to make sure you didn't think that patches weren't welcome.

relan commented 8 years ago

Confirming that now it works. Thanks for the quick fix!

relan commented 8 years ago

I have a question about the current APK concept. As I understand it, it's the latest stable version of an app. So, versioncode in the app CV sets the boundary between release and pre-release versions.

This works well until we have multiple APKs for various architectures with different vercodes. For example, an app has the following APKs in the repo (version string: version code, arch):

CV should probably have versioncode set to 34 (?). But which APK to select (32 or 34) depends on the device. So, we need ABI, SDK, etc. filters. But fdroidcl download command is meant to be used without any connected devices. How will it work with filters?

mvdan commented 8 years ago

This is why #6 is needed. Otherwise, we could have some sort of "default" device with its details stored in the cache.