Affix

 view release on metacpan or  search on metacpan

t/070_security_fixes.t  view on Meta::CPAN

    ok eval "package Test::H7Valid; $code; 1", 'Generated constant compiles' or diag "eval error: $@";

    # Evil macro name — should NOT install into symbol table
    my $evil = Affix::Wrap::Macro->new( name => 'EVIL; system("echo PWNED")', value => '1', );
    $result = $evil->affix( undef, 'Test::H7Evil' );
    ok defined $result, 'affix() returns for evil name (no crash)';

    # The evil name must NOT be accessible as a subroutine in the target package
    ok !defined $Test::H7Evil::{'EVIL; system("echo PWNED")'}, 'Evil name NOT installed in symbol table';
};
#
subtest 'H7/H8: Enum constant name validation' => sub {
    use Affix qw[Enum];
    my $type = Enum [ [ RED => 0 ], [ GREEN => 1 ], [ BLUE => 2 ], ];
    ok defined $type, 'Enum type created';
    my ( $const_map, $val_map ) = $type->resolve();
    is ref $const_map, 'HASH', 'const_map is a hash';
    ok exists $const_map->{RED},   'RED in const_map';
    ok exists $const_map->{GREEN}, 'GREEN in const_map';
    ok exists $const_map->{BLUE},  'BLUE in const_map';
};
#
subtest 'M4: Double-quote C string literal stripping in affix_type' => sub {
    use Affix::Wrap;
    my $macro = Affix::Wrap::Macro->new( name => 'GREETING', value => '"Hello World"', );
    my $code  = $macro->affix_type;
    like $code,   qr/use constant GREETING => 'Hello World'/, 'Double-quoted string stripped of outer quotes';
    unlike $code, qr/"Hello World"/,                          'No remaining double quotes in generated code';
    ok eval "package Test::M4; $code; 1", 'Generated constant compiles' or diag "eval error: $@";
};
#
subtest 'M5: Path traversal prevention in Affix::Build output name' => sub {
    skip_all 'No CC' unless $Config{cc};
    use Affix::Build;
    my $TMP_DIR = Path::Tiny->tempdir( CLEANUP => 1 );
    my $c       = Affix::Build->new( build_dir => $TMP_DIR, name => '../../etc/passwd' );
    $c->add( \<<~'', lang => 'c' );
        #include <stdio.h>
        int traversal_test(void) { return 42; }

    ok eval { $c->compile_and_link() }, 'Compiled despite malicious name';
    my $lib = $c->link;
    unlike "$lib", qr/\.\.[\/\\]/, 'Output path contains no path traversal';
};
#
subtest 'M13: Division by zero in _calculate_expr' => sub {
    use Affix qw[Enum];

    # _calculate_expr is in Affix::Type::Enum, accessible via resolve
    # We can test indirectly by defining enums with division expressions
    my $type = Enum [ [ HALF => '10 / 2' ], [ ZERO => '10 / 0' ], [ REM => '10 % 3' ], [ REMZ => '10 % 0' ], ];
    ok defined $type, 'Enum with division expressions created';
    my ( $const_map, $val_map ) = $type->resolve();
    is $const_map->{HALF}, 5, '10 / 2 = 5';
    is $const_map->{ZERO}, 0, '10 / 0 = 0 (not crash)';
    is $const_map->{REM},  1, '10 % 3 = 1';
    is $const_map->{REMZ}, 0, '10 % 0 = 0 (not crash)';
};
#
subtest 'M14/L12: DynaLoader typo fix' => sub {
    is $DynaLoader::dl_debug, 0, '$DynaLoader::dl_debug is set to 0 (not 1, no noisy bootstrap)';
};
done_testing;



( run in 0.608 second using v1.01-cache-2.11-cpan-84de2e75c66 )