Merge pull request #45 from kpawlak/task-logging-and-check

Logging improvements and buffers security
This commit is contained in:
mborgerding 2020-05-26 22:21:27 -04:00 committed by GitHub
commit f0a47de6aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 24 deletions

View File

@ -15,10 +15,11 @@
#define _kiss_fft_guts_h #define _kiss_fft_guts_h
#include "kiss_fft.h" #include "kiss_fft.h"
#include "kiss_fft_log.h"
#include <limits.h> #include <limits.h>
#define MAXFACTORS 32 #define MAXFACTORS 32
/* e.g. an fft of length 128 has 4 factors /* e.g. an fft of length 128 has 4 factors
as far as kissfft is concerned as far as kissfft is concerned
4*4*4*2 4*4*4*2
*/ */
@ -56,7 +57,7 @@ struct kiss_fft_state{
#if defined(CHECK_OVERFLOW) #if defined(CHECK_OVERFLOW)
# define CHECK_OVERFLOW_OP(a,op,b) \ # define CHECK_OVERFLOW_OP(a,op,b) \
if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } KISS_FFT_WARNING("overflow (%d " #op" %d) = %ld", (a),(b),(SAMPPROD)(a) op (SAMPPROD)(b)); }
#endif #endif
@ -146,17 +147,17 @@ struct kiss_fft_state{
/* a debugging function */ /* a debugging function */
#define pcpx(c)\ #define pcpx(c)\
fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) KISS_FFT_DEBUG("%g + %gi\n",(double)((c)->r),(double)((c)->i))
#ifdef KISS_FFT_USE_ALLOCA #ifdef KISS_FFT_USE_ALLOCA
// define this to allow use of alloca instead of malloc for temporary buffers // define this to allow use of alloca instead of malloc for temporary buffers
// Temporary buffers are used in two case: // Temporary buffers are used in two case:
// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 // 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. // 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform.
#include <alloca.h> #include <alloca.h>
#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
#define KISS_FFT_TMP_FREE(ptr) #define KISS_FFT_TMP_FREE(ptr)
#else #else
#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)

View File

@ -203,6 +203,10 @@ static void kf_bfly_generic(
int Norig = st->nfft; int Norig = st->nfft;
kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p); kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
if (scratch == NULL){
KISS_FFT_ERROR("Memory allocation failed.");
return;
}
for ( u=0; u<m; ++u ) { for ( u=0; u<m; ++u ) {
k=u; k=u;
@ -244,7 +248,7 @@ void kf_work(
const kiss_fft_cpx * Fout_end = Fout + p*m; const kiss_fft_cpx * Fout_end = Fout + p*m;
#ifdef _OPENMP #ifdef _OPENMP
// use openmp extensions at the // use openmp extensions at the
// top-level (not recursive) // top-level (not recursive)
if (fstride==1 && p<=5 && m!=1) if (fstride==1 && p<=5 && m!=1)
{ {
@ -252,15 +256,15 @@ void kf_work(
// execute the p different work units in different threads // execute the p different work units in different threads
# pragma omp parallel for # pragma omp parallel for
for (k=0;k<p;++k) for (k=0;k<p;++k)
kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st); kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
// all threads have joined by this point // all threads have joined by this point
switch (p) { switch (p) {
case 2: kf_bfly2(Fout,fstride,st,m); break; case 2: kf_bfly2(Fout,fstride,st,m); break;
case 3: kf_bfly3(Fout,fstride,st,m); break; case 3: kf_bfly3(Fout,fstride,st,m); break;
case 4: kf_bfly4(Fout,fstride,st,m); break; case 4: kf_bfly4(Fout,fstride,st,m); break;
case 5: kf_bfly5(Fout,fstride,st,m); break; case 5: kf_bfly5(Fout,fstride,st,m); break;
default: kf_bfly_generic(Fout,fstride,st,m,p); break; default: kf_bfly_generic(Fout,fstride,st,m,p); break;
} }
return; return;
@ -276,7 +280,7 @@ void kf_work(
do{ do{
// recursive call: // recursive call:
// DFT of size m*p performed by doing // DFT of size m*p performed by doing
// p instances of smaller DFTs of size m, // p instances of smaller DFTs of size m,
// each one takes a decimated version of the input // each one takes a decimated version of the input
kf_work( Fout , f, fstride*p, in_stride, factors,st); kf_work( Fout , f, fstride*p, in_stride, factors,st);
f += fstride*in_stride; f += fstride*in_stride;
@ -285,21 +289,21 @@ void kf_work(
Fout=Fout_beg; Fout=Fout_beg;
// recombine the p smaller DFTs // recombine the p smaller DFTs
switch (p) { switch (p) {
case 2: kf_bfly2(Fout,fstride,st,m); break; case 2: kf_bfly2(Fout,fstride,st,m); break;
case 3: kf_bfly3(Fout,fstride,st,m); break; case 3: kf_bfly3(Fout,fstride,st,m); break;
case 4: kf_bfly4(Fout,fstride,st,m); break; case 4: kf_bfly4(Fout,fstride,st,m); break;
case 5: kf_bfly5(Fout,fstride,st,m); break; case 5: kf_bfly5(Fout,fstride,st,m); break;
default: kf_bfly_generic(Fout,fstride,st,m,p); break; default: kf_bfly_generic(Fout,fstride,st,m,p); break;
} }
} }
/* facbuf is populated by p1,m1,p2,m2, ... /* facbuf is populated by p1,m1,p2,m2, ...
where where
p[i] * m[i] = m[i-1] p[i] * m[i] = m[i-1]
m0 = n */ m0 = n */
static static
void kf_factor(int n,int * facbuf) void kf_factor(int n,int * facbuf)
{ {
int p=4; int p=4;
@ -369,7 +373,19 @@ void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,
if (fin == fout) { if (fin == fout) {
//NOTE: this is not really an in-place FFT algorithm. //NOTE: this is not really an in-place FFT algorithm.
//It just performs an out-of-place FFT into a temp buffer //It just performs an out-of-place FFT into a temp buffer
if (fout == NULL){
KISS_FFT_ERROR("fout buffer NULL.");
return;
}
kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
if (tmpbuf == NULL){
KISS_FFT_ERROR("Memory allocation error.");
return;
}
kf_work(tmpbuf,fin,1,in_stride, st->factors,st); kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
KISS_FFT_TMP_FREE(tmpbuf); KISS_FFT_TMP_FREE(tmpbuf);

36
kiss_fft_log.h Normal file
View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
* This file is part of KISS FFT - https://github.com/mborgerding/kissfft
*
* SPDX-License-Identifier: BSD-3-Clause
* See COPYING file for more information.
*/
#ifndef kiss_fft_log_h
#define kiss_fft_log_h
#define ERROR 1
#define WARNING 2
#define INFO 3
#define DEBUG 4
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#if defined(NDEBUG)
# define KISS_FFT_LOG_MSG(severity, ...) ((void)0)
#else
# define KISS_FFT_LOG_MSG(severity, ...) \
fprintf(stderr, "[" #severity "] " __FILE__ ":" TOSTRING(__LINE__) " "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n")
#endif
#define KISS_FFT_ERROR(...) KISS_FFT_LOG_MSG(ERROR, __VA_ARGS__)
#define KISS_FFT_WARNING(...) KISS_FFT_LOG_MSG(WARNING, __VA_ARGS__)
#define KISS_FFT_INFO(...) KISS_FFT_LOG_MSG(INFO, __VA_ARGS__)
#define KISS_FFT_DEBUG(...) KISS_FFT_LOG_MSG(DEBUG, __VA_ARGS__)
#endif /* kiss_fft_log_h */

View File

@ -27,7 +27,7 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenme
size_t subsize = 0, memneeded; size_t subsize = 0, memneeded;
if (nfft & 1) { if (nfft & 1) {
fprintf(stderr,"Real FFT optimization must be even.\n"); KISS_FFT_ERROR("Real FFT optimization must be even.");
return NULL; return NULL;
} }
nfft >>= 1; nfft >>= 1;
@ -67,7 +67,7 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
if ( st->substate->inverse) { if ( st->substate->inverse) {
fprintf(stderr,"kiss fft usage error: improper alloc\n"); KISS_FFT_ERROR("kiss fft usage error: improper alloc");
exit(1); exit(1);
} }
@ -79,12 +79,12 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
* contains the sum of the even-numbered elements of the input time sequence * contains the sum of the even-numbered elements of the input time sequence
* The imag part is the sum of the odd-numbered elements * The imag part is the sum of the odd-numbered elements
* *
* The sum of tdc.r and tdc.i is the sum of the input time sequence. * The sum of tdc.r and tdc.i is the sum of the input time sequence.
* yielding DC of input time sequence * yielding DC of input time sequence
* The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1...
* yielding Nyquist bin of input time sequence * yielding Nyquist bin of input time sequence
*/ */
tdc.r = st->tmpbuf[0].r; tdc.r = st->tmpbuf[0].r;
tdc.i = st->tmpbuf[0].i; tdc.i = st->tmpbuf[0].i;
C_FIXDIV(tdc,2); C_FIXDIV(tdc,2);
@ -92,14 +92,14 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *fr
CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
freqdata[0].r = tdc.r + tdc.i; freqdata[0].r = tdc.r + tdc.i;
freqdata[ncfft].r = tdc.r - tdc.i; freqdata[ncfft].r = tdc.r - tdc.i;
#ifdef USE_SIMD #ifdef USE_SIMD
freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
#else #else
freqdata[ncfft].i = freqdata[0].i = 0; freqdata[ncfft].i = freqdata[0].i = 0;
#endif #endif
for ( k=1;k <= ncfft/2 ; ++k ) { for ( k=1;k <= ncfft/2 ; ++k ) {
fpk = st->tmpbuf[k]; fpk = st->tmpbuf[k];
fpnk.r = st->tmpbuf[ncfft-k].r; fpnk.r = st->tmpbuf[ncfft-k].r;
fpnk.i = - st->tmpbuf[ncfft-k].i; fpnk.i = - st->tmpbuf[ncfft-k].i;
C_FIXDIV(fpk,2); C_FIXDIV(fpk,2);
@ -122,7 +122,7 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *t
int k, ncfft; int k, ncfft;
if (st->substate->inverse == 0) { if (st->substate->inverse == 0) {
fprintf (stderr, "kiss fft usage error: improper alloc\n"); KISS_FFT_ERROR("kiss fft usage error: improper alloc");
exit (1); exit (1);
} }
@ -145,7 +145,7 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *t
C_MUL (fok, tmp, st->super_twiddles[k-1]); C_MUL (fok, tmp, st->super_twiddles[k-1]);
C_ADD (st->tmpbuf[k], fek, fok); C_ADD (st->tmpbuf[k], fek, fok);
C_SUB (st->tmpbuf[ncfft - k], fek, fok); C_SUB (st->tmpbuf[ncfft - k], fek, fok);
#ifdef USE_SIMD #ifdef USE_SIMD
st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
#else #else
st->tmpbuf[ncfft - k].i *= -1; st->tmpbuf[ncfft - k].i *= -1;