Skip to content

libexpr-c: fix nix_get_external #15954

Open
Lillecarl wants to merge 2 commits into
NixOS:masterfrom
Lillecarl:nix_get_external
Open

libexpr-c: fix nix_get_external #15954
Lillecarl wants to merge 2 commits into
NixOS:masterfrom
Lillecarl:nix_get_external

Conversation

@Lillecarl
Copy link
Copy Markdown

AI Disclamier

This change is made in China ™️

Change explanation

nix_get_external reads from an already-initialized nix_value (set via nix_init_external). Every other getter in the file (nix_get_bool, nix_get_int, nix_get_float, nix_get_string, nix_get_path_string) uses check_value_in, which asserts the value IS initialized. nix_get_external was the sole getter using check_value_out, which asserts the value is UNinitialized and throws "nix_value already initialized" for any valid external value — making the function always fail.

Also made the value parameter const to match all other getters.

Motivation

I'm working on updating the cffi Python bindings from tweag so we can have the Nix we deserve in Python 😄

https://github.com/NixOS/nix/milestone/52

Context

I found this when creating unit tests at https://github.com/lillecarl/python-nix to cover the entire API surface and the external value tests just wouldn't pass.

@yorickvP

@Lillecarl Lillecarl requested a review from edolstra as a code owner June 1, 2026 20:50
@github-actions github-actions Bot added the c api Nix as a C library with a stable interface label Jun 1, 2026
@xokdvium
Copy link
Copy Markdown
Contributor

xokdvium commented Jun 1, 2026

Can we have a unit test for this?

Comment thread src/libexpr-c/nix_api_value.h Outdated
@Lillecarl
Copy link
Copy Markdown
Author

@xokdvium I replicated the test from python-nix and cloned some existing getter value tests

Comment thread src/libexpr-tests/nix_api_external.cc Outdated
@xokdvium
Copy link
Copy Markdown
Contributor

xokdvium commented Jun 1, 2026

cc @roberth

Lillecarl added 2 commits June 2, 2026 09:46
…_value_out

nix_get_external reads from an already-initialized nix_value (set via
nix_init_external). Every other getter in the file (nix_get_bool,
nix_get_int, nix_get_float, nix_get_string, nix_get_path_string) uses
check_value_in, which asserts the value IS initialized.  nix_get_external
was the sole getter using check_value_out, which asserts the value is
UNinitialized and throws "nix_value already initialized" for any valid
external value — making the function always fail.
Regression test for the check_value_out → check_value_in fix: nix_get_external
reads from an already-initialized value and must use check_value_in, not
check_value_out (which asserts the value is NOT initialized).

Added:
- nix_get_external_roundtrip: create external → init → force → get back
- nix_get_external_invalid: null and uninitialized value error paths
- nix_get_external_value_content_null: null ExternalValue* gracefully
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c api Nix as a C library with a stable interface

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants