You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
2.0 KiB

  1. From 7d65f89defb092b63bcbc5d98349fb222ca73b3c Mon Sep 17 00:00:00 2001
  2. From: Antonio Larrosa <larrosa@kde.org>
  3. Date: Mon, 6 Mar 2017 13:54:52 +0100
  4. Subject: [PATCH] Check for multiplication overflow in sfconvert
  5. Checks that a multiplication doesn't overflow when
  6. calculating the buffer size, and if it overflows,
  7. reduce the buffer size instead of failing.
  8. This fixes the 00192-audiofile-signintoverflow-sfconvert case
  9. in #41
  10. ---
  11. sfcommands/sfconvert.c | 34 ++++++++++++++++++++++++++++++++--
  12. 1 file changed, 32 insertions(+), 2 deletions(-)
  13. diff --git a/sfcommands/sfconvert.c b/sfcommands/sfconvert.c
  14. index 80a1bc4..970a3e4 100644
  15. --- a/sfcommands/sfconvert.c
  16. +++ b/sfcommands/sfconvert.c
  17. @@ -45,6 +45,33 @@ void printusage (void);
  18. void usageerror (void);
  19. bool copyaudiodata (AFfilehandle infile, AFfilehandle outfile, int trackid);
  20. +int firstBitSet(int x)
  21. +{
  22. + int position=0;
  23. + while (x!=0)
  24. + {
  25. + x>>=1;
  26. + ++position;
  27. + }
  28. + return position;
  29. +}
  30. +
  31. +#ifndef __has_builtin
  32. +#define __has_builtin(x) 0
  33. +#endif
  34. +
  35. +int multiplyCheckOverflow(int a, int b, int *result)
  36. +{
  37. +#if (defined __GNUC__ && __GNUC__ >= 5) || ( __clang__ && __has_builtin(__builtin_mul_overflow))
  38. + return __builtin_mul_overflow(a, b, result);
  39. +#else
  40. + if (firstBitSet(a)+firstBitSet(b)>31) // int is signed, so we can't use 32 bits
  41. + return true;
  42. + *result = a * b;
  43. + return false;
  44. +#endif
  45. +}
  46. +
  47. int main (int argc, char **argv)
  48. {
  49. if (argc == 2)
  50. @@ -323,8 +350,11 @@ bool copyaudiodata (AFfilehandle infile, AFfilehandle outfile, int trackid)
  51. {
  52. int frameSize = afGetVirtualFrameSize(infile, trackid, 1);
  53. - const int kBufferFrameCount = 65536;
  54. - void *buffer = malloc(kBufferFrameCount * frameSize);
  55. + int kBufferFrameCount = 65536;
  56. + int bufferSize;
  57. + while (multiplyCheckOverflow(kBufferFrameCount, frameSize, &bufferSize))
  58. + kBufferFrameCount /= 2;
  59. + void *buffer = malloc(bufferSize);
  60. AFframecount totalFrames = afGetFrameCount(infile, AF_DEFAULT_TRACK);
  61. AFframecount totalFramesWritten = 0;
  62. --
  63. 2.11.0