Skip to content

Commit

Permalink
vsearch: fix segv if vsearch $x arg is empty; add support for bad val…
Browse files Browse the repository at this point in the history
…ues in $vals argument
  • Loading branch information
djerius committed Jul 25, 2023
1 parent 5ce5913 commit 5cf6f70
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 12 deletions.
47 changes: 35 additions & 12 deletions Basic/Primitive/primitive.pd
Original file line number Diff line number Diff line change
Expand Up @@ -2913,17 +2913,39 @@ for my $func ( [


my $code = undent q[
PDL_Indx n1 = $SIZE(n)-1;
PDL_Indx low = %LOW%;
PDL_Indx high = %HIGH%;
PDL_Indx mid;
if ( $SIZE(n) == 0 ){
broadcastloop %{
loop(n) %{
$SETBAD(idx());
%}
%}
}
else {
broadcastloop %{
$GENERIC() value = $vals();
loop(n) %{
/* determine sort order of data */
int up = %UP%;
%CODE%
----
if ( $ISGOOD(vals()) ) {
PDL_Indx n1 = $SIZE(n)-1;
PDL_Indx low = %LOW%;
PDL_Indx high = %HIGH%;
PDL_Indx mid;
$GENERIC() value = $vals();
/* determine sort order of data */
int up = %UP%;
%CODE%
}
else {
$SETBAD(idx());
}
%}
%}
}
----
];

my $doc = undent q[
Expand All @@ -2936,7 +2958,8 @@ for my $func ( [
$idx = %FUNC%($vals, $x);
C<$x> must be sorted, but may be in decreasing or increasing
order.
order. if C<$x> is empty, then all values in C<$idx> will be
set to the bad value.
%PRE%
%BODY%
Expand All @@ -2952,8 +2975,8 @@ for my $func ( [

pp_def(
$func,
HandleBad => 0,
BadDoc => 'needs major (?) work to handles bad values',
HandleBad => 1,
BadDoc => 'bad values in vals() result in bad values in idx()',
Pars => 'vals(); x(n); indx [o]idx()',
GenericTypes => $F, # too restrictive ?
Code => $code,
Expand Down
27 changes: 27 additions & 0 deletions t/primitive/vsearch.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use strict;
use warnings;
use Test2::V0 '!float';
use Test2::Util;

use PDL::LiteF;
use Test::Lib;
Expand Down Expand Up @@ -375,6 +376,14 @@ for my $mode ( sort keys %search ) {
$so->{equal} ),
'equal elements';

my $badmask = $so->{x}->random < 0.25;
my $badx = $so->{x}->setbadif( $badmask );
my $bad_eq = $so->{equal}->setbadif( $badmask );

ok tapprox( vsearch( $badx, $so->{x}, { mode => $mode } ),
$bad_eq ),
'equal elements w/ bad vals';

ok tapprox(
vsearch( $so->{x} - 5, $so->{x}, { mode => $mode } ),
$so->{nequal_m} ),
Expand Down Expand Up @@ -446,4 +455,22 @@ for my $mode ( sort keys %search ) {
ok tapprox( $indx0, $indx1 ), 'explicit ndarray == implicit ndarray';
}

subtest regressions => sub {

subtest '$xs->is_empty' => sub {

skip 'check for regression requires fork' unless Test2::Util::CAN_FORK;
require Test2::AsyncSubtest;

my $ast = Test2::AsyncSubtest->new( name => 'vsearch' );
$ast->run_fork(
sub {
ok lives { pdl( [0] )->vsearch_bin_inclusive( pdl( [] ) ) }
}
);
$ast->finish;

};

};
done_testing;

0 comments on commit 5cf6f70

Please sign in to comment.