Skip to content

[CORE] Fix some logic errors reported in #4214 - #4271

Merged
ptitSeb merged 1 commit into
ptitSeb:mainfrom
zengdage:myalign
Sep 11, 2026
Merged

[CORE] Fix some logic errors reported in #4214#4271
ptitSeb merged 1 commit into
ptitSeb:mainfrom
zengdage:myalign

Conversation

@zengdage

Copy link
Copy Markdown
Contributor
  1. Preserve state across spaces and %m modifiers.

  2. Initialize GVariant parser state(tmp) for a and @ formats.

  3. Advance the st only when an argument is read from stack.

  4. Ignore NULL in XCB display registrations.

  5. Fix space handling in the 32-bit wide scanf parser.

@ptitSeb

ptitSeb commented Aug 19, 2026

Copy link
Copy Markdown
Owner

I'l validate this one next week, after my vacaccions, so next week.

@zengdage

Copy link
Copy Markdown
Contributor Author

Test case as follow, previously these programs failed and this pr makes them run properly.

//   gcc $(pkg-config --cflags glib-2.0) -O1 myalign_fix.c -o myalign_fix $(pkg-config --libs glib-2.0)

#include <stdio.h>
#include <string.h>
#include <wchar.h>
#include <glib.h>

static int failures;
static int total;

static void check(const char* name, const char* got, const char* expected)
{
    ++total;
    if (strcmp(got, expected) != 0) {
        printf("[FAIL] %s: got \"%s\", expected \"%s\"\n", name, got, expected);
        ++failures;
    } else {
        printf("[PASS] %s: \"%s\"\n", name, got);
    }
}

static void check_variant(const char* name, GVariant* v, const char* expected)
{
    if (v) {
        gchar* s = g_variant_print(v, TRUE);
        check(name, s, expected);
        g_free(s);
        g_variant_unref(v);
    } else {
        printf("[FAIL] %s: NULL\n", name);
        ++failures;
        ++total;
    }
}

int main(void)
{
    char buf[64];

    snprintf(buf, sizeof(buf), "[% d][% 6d]", 7, 8);
    check("printf % d", buf, "[ 7][     8]");

    /* @i as 6th arg (first from stack) */
    check_variant("overflow @i",
        g_variant_new("(iiiii@i)", 1, 2, 3, 4, 5, g_variant_new("i", 42)),
        "(1, 2, 3, 4, 5, 42)");

    /* two @i on stack — second relies on tmp reset */
    check_variant("overflow @i@i",
        g_variant_new("(iiiii@i@i)", 1, 2, 3, 4, 5,
            g_variant_new("i", 10), g_variant_new("i", 20)),
        "(1, 2, 3, 4, 5, 10, 20)");

    /* @(ii) on stack — exercises tmp nesting in state 3 */
    check_variant("overflow @(ii)",
        g_variant_new("(iiiii@(ii))", 1, 2, 3, 4, 5,
            g_variant_new("(ii)", 6, 7)),
        "(1, 2, 3, 4, 5, (6, 7))");

    /* ai as 6th arg — exercises state 1 in overflow */
    GVariantBuilder* b = g_variant_builder_new(G_VARIANT_TYPE("ai"));
    g_variant_builder_add(b, "i", 8);
    g_variant_builder_add(b, "i", 9);
    check_variant("overflow ai",
        g_variant_new("(iiiiiai)", 1, 2, 3, 4, 5, b),
        "(1, 2, 3, 4, 5, [8, 9])");
    g_variant_builder_unref(b);

    printf("\n%d passed, %d failed\n", total - failures, failures);
    return failures != 0;
}

Comment thread src/libtools/myalign32.c
Comment thread src/libtools/myalign32.c
1. Preserve `state` across spaces in printf/wprintf stack aligners. A space
inside a format specifier should not reset the parsing state.

2. Initialize and reset the GVariant parser nesting counter (`tmp`) when
entering `a` (array) and `@` (GVariant*) states.

3. Advance `st` only when an argument is actually read from the stack in
`myStackAlignGVariantNew`. Previously `++st` was executed unconditionally,
even for register arguments, causing subsequent stack arguments to be read
from wrong offsets.
@ptitSeb
ptitSeb merged commit c79152c into ptitSeb:main Sep 11, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants