diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-08 16:02:00 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2022-04-08 16:02:00 +0000 |
commit | 2e66659bb231b4b22d6aeaa6e937f53247869c0b (patch) | |
tree | 4f382bd3a394fd8e4eb992c01d71db19569e77d2 | |
parent | ec5e4e74396af037d9ac6609c6667152b8e8cbe7 (diff) | |
parent | 483c601b7288f246eda807b5bad3f68a11b328e2 (diff) | |
download | tremolo-aml_tz2_305400100.tar.gz |
Snap for 8426163 from 483c601b7288f246eda807b5bad3f68a11b328e2 to mainline-tzdata2-releaseandroid-mainline-12.0.0_r112aml_tz2_305400500aml_tz2_305400300aml_tz2_305400100aml_tz2_304500300aml_tz2_303900110aml_tz2_303900102aml_tz2_303800002aml_tz2_303800001aml_tz2_303200001android12-mainline-tzdata2-releaseaml_tz2_305400100
Change-Id: I768d2fdc107a55f97967683f0a57a133678ff125
-rw-r--r-- | Android.bp | 49 | ||||
-rw-r--r-- | METADATA | 3 | ||||
-rw-r--r-- | OWNERS | 7 | ||||
-rw-r--r-- | TEST_MAPPING | 7 | ||||
-rw-r--r-- | Tremolo/bitwiseARM.s | 5 | ||||
-rw-r--r-- | Tremolo/codebook.c | 12 | ||||
-rw-r--r-- | Tremolo/dpen.s | 10 | ||||
-rw-r--r-- | Tremolo/floor0.c | 32 | ||||
-rw-r--r-- | Tremolo/floor1ARM.s | 1 | ||||
-rw-r--r-- | Tremolo/floor1LARM.s | 1 | ||||
-rw-r--r-- | Tremolo/mdct.c | 2 | ||||
-rw-r--r-- | Tremolo/mdctARM.s | 15 | ||||
-rw-r--r-- | Tremolo/mdctLARM.s | 7 | ||||
-rw-r--r-- | fuzzer/Android.bp | 46 | ||||
-rw-r--r-- | fuzzer/README.md | 49 | ||||
-rw-r--r-- | fuzzer/vorbis_dec_fuzzer.cpp | 197 | ||||
-rw-r--r-- | fuzzer/vorbis_dec_fuzzer.dict | 5 | ||||
-rw-r--r-- | tests/Android.bp | 38 | ||||
-rw-r--r-- | tests/AndroidTest.xml | 28 | ||||
-rw-r--r-- | tests/README.md | 39 | ||||
-rw-r--r-- | tests/VorbisDecoderTest.cpp | 343 | ||||
-rw-r--r-- | tests/VorbisDecoderTestEnvironment.h | 83 | ||||
-rw-r--r-- | tests/oob_oggpack_look/Android.bp | 43 | ||||
-rw-r--r-- | tests/test_floor0.cpp (renamed from tests/oob_oggpack_look/test_floor0.cpp) | 0 |
24 files changed, 47 insertions, 975 deletions
@@ -1,37 +1,6 @@ -package { - default_applicable_licenses: ["external_tremolo_license"], -} - -// Added automatically by a large-scale-change that took the approach of -// 'apply every license found to every target'. While this makes sure we respect -// every license restriction, it may not be entirely correct. -// -// e.g. GPL in an MIT project might only apply to the contrib/ directory. -// -// Please consider splitting the single license below into multiple licenses, -// taking care not to lose any license_kind information, and overriding the -// default license using the 'licenses: [...]' property on targets as needed. -// -// For unused files, consider creating a 'fileGroup' with "//visibility:private" -// to attach the license to, and including a comment whether the files may be -// used in the current project. -// See: http://go/android-license-faq -license { - name: "external_tremolo_license", - visibility: [":__subpackages__"], - license_kinds: [ - "SPDX-license-identifier-Apache-2.0", - "SPDX-license-identifier-BSD", - ], - license_text: [ - "NOTICE", - ], -} - cc_library { name: "libvorbisidec", vendor_available: true, - host_supported: true, srcs: [ "Tremolo/bitwise.c", @@ -51,18 +20,27 @@ cc_library { arch: { arm: { - cflags: ["-D_ARM_ASSEM_"], - instruction_set: "arm", srcs: [ "Tremolo/bitwiseARM.s", "Tremolo/dpen.s", "Tremolo/floor1ARM.s", "Tremolo/mdctARM.s", ], + cflags: ["-D_ARM_ASSEM_"], + // Assembly code in asm_arm.h does not compile with Clang. + clang_asflags: ["-no-integrated-as"], + + instruction_set: "arm", }, arm64: { cflags: ["-DONLY_C"], }, + mips: { + cflags: ["-DONLY_C"], + }, + mips64: { + cflags: ["-DONLY_C"], + }, x86: { cflags: ["-DONLY_C"], }, @@ -90,10 +68,5 @@ cc_library { misc_undefined: ["bounds"], }, - target: { - darwin: { - enabled: false, - }, - }, min_sdk_version: "29", } diff --git a/METADATA b/METADATA deleted file mode 100644 index d97975c..0000000 --- a/METADATA +++ /dev/null @@ -1,3 +0,0 @@ -third_party { - license_type: NOTICE -} @@ -1,3 +1,4 @@ -# owners for external/tremolo -include platform/frameworks/av:/media/janitors/codec_OWNERS -essick@google.com +# Default code reviewers picked from top 3 or more developers. +# Please update this list if you find better candidates. +marcone@google.com +dwkang@google.com diff --git a/TEST_MAPPING b/TEST_MAPPING index d58e4e0..fed9cac 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,13 +1,6 @@ { "presubmit": [ { "name": "oob_oggpack_look" } - ], - - // tests which require dynamic content - // invoke with: atest -- --enable-module-dynamic-download=true - // TODO(b/148094059): unit tests not allowed to download content - "dynamic-presubmit": [ - { "name": "VorbisDecoderTest" } ] } diff --git a/Tremolo/bitwiseARM.s b/Tremolo/bitwiseARM.s index 1c533a2..5805977 100644 --- a/Tremolo/bitwiseARM.s +++ b/Tremolo/bitwiseARM.s @@ -39,11 +39,6 @@ .global oggpack_readinit .global oggpack_read - .type oggpack_look, %function - .type oggpack_adv, %function - .type oggpack_readinit, %function - .type oggpack_read, %function - oggpack_look: @ r0 = oggpack_buffer *b @ r1 = int bits diff --git a/Tremolo/codebook.c b/Tremolo/codebook.c index 5a57a71..4e9e570 100644 --- a/Tremolo/codebook.c +++ b/Tremolo/codebook.c @@ -859,11 +859,8 @@ long vorbis_book_decodevs_add(codebook *book,ogg_int32_t *a, for (j=0;j<step;j++){ if(decode_map(book,b,v,point))return -1; - for(i=0,o=j;i<book->dim;i++,o+=step){ - if (__builtin_add_overflow(a[o], v[i], &a[o])){ - a[o] = v[i] > 0 ? INT32_MAX : INT32_MIN; - } - } + for(i=0,o=j;i<book->dim;i++,o+=step) + a[o]+=v[i]; } } return 0; @@ -934,10 +931,7 @@ long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, for(i=offset;i<offset+n;){ if(decode_map(book,b,v,point))return -1; for (j=0;j<book->dim && i < offset + n;j++){ - if (__builtin_add_overflow(a[chptr][i], v[j], &a[chptr][i])) { - a[chptr][i] = v[j] > 0 ? INT32_MAX : INT32_MIN; - } - chptr++; + a[chptr++][i]+=v[j]; if(chptr==ch){ chptr=0; i++; diff --git a/Tremolo/dpen.s b/Tremolo/dpen.s index cc492cf..344e41b 100644 --- a/Tremolo/dpen.s +++ b/Tremolo/dpen.s @@ -40,12 +40,6 @@ .global vorbis_book_decodevv_add .global _checksum - .type decode_packed_entry_number, %function - .type decode_packed_entry_number_REALSTART, %function - .type decode_map, %function - .type vorbis_book_decodevv_add, %function - .type _checksum, %function - .extern oggpack_adv .extern oggpack_look .extern oggpack_eop @@ -143,7 +137,7 @@ m1_loop: BLT duff CMP r8, r7 @ if bit==0 (chase+bit==chase) (sets C) - LDRBNE r14,[r6, r7] @ r14= t[chase] + LDRNEB r14,[r6, r7] @ r14= t[chase] MOVEQ r14,#128 ADC r12,r8, r6 @ r12= chase+bit+1+t LDRB r14,[r12,r14,LSR #7] @ r14= t[chase+bit+1+(!bit || t[chase]0x0x80)] @@ -202,7 +196,7 @@ m3_loop: MOV r7, r7, LSL #1 CMP r8, r7 @ if bit==0 (chase+bit==chase) sets C - LDRHNE r14,[r6, r7] @ r14= t[chase] + LDRNEH r14,[r6, r7] @ r14= t[chase] MOVEQ r14,#0x8000 ADC r12,r8, r14,LSR #15 @ r12= 1+((chase+bit)<<1)+(!bit || t[chase]0x0x8000) ADC r12,r12,r14,LSR #15 @ r12= t + (1+chase+bit+(!bit || t[chase]0x0x8000))<<1 diff --git a/Tremolo/floor0.c b/Tremolo/floor0.c index 11452c5..ea814e5 100644 --- a/Tremolo/floor0.c +++ b/Tremolo/floor0.c @@ -103,34 +103,28 @@ static inline ogg_int32_t vorbis_coslook2_i(long a){ (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14); } -/* Values in barklook are defined such that toBARK(x) is an approximation to - POW(2, 15) * ((13.1*ATAN(0.00074*(x)))+(2.24*ATAN((x)*(x)*0.0000000185))+(0.0001*(x))) */ -static const ogg_uint16_t barklook[]={ +static const ogg_uint16_t barklook[54]={ 0,51,102,154, 206,258,311,365, 420,477,535,594, 656,719,785,854, 926,1002,1082,1166, 1256,1352,1454,1564, 1683,1812,1953,2107, 2276,2463,2670,2900, 3155,3440,3756,4106, 4493,4919,5387,5901, 6466,7094,7798,8599, 9528,10623,11935,13524, - 15453,17775,20517,23667, 27183,31004,35069 + 15453,17775,20517,23667, 27183,31004 }; /* used in init only; interpolate the long way */ -static inline ogg_int32_t toBARK(ogg_uint16_t n){ +static inline ogg_int32_t toBARK(int n){ int i; - int barklook_size = (sizeof(barklook) / sizeof(barklook[0])); - for(i=1;i<barklook_size;i++){ - if(n<barklook[i]){ - i--; - return (i<<14)+(((n-barklook[i])* - ((1UL<<31)/(barklook[i+1]-barklook[i])))>>17); - } + for(i=0;i<54;i++) + if(n>=barklook[i] && n<barklook[i+1])break; + + if(i==54){ + return 54<<14; + }else{ + return (i<<14)+(((n-barklook[i])* + ((1UL<<31)/(barklook[i+1]-barklook[i])))>>17); } - /* for a valid input n, which is half of info->rate (i.e. max 32767 - as info->rate is 16 bit unsigned value), loop above will return - an output. So the following return will be used only when toBARK() - is called with invalid value */ - return (barklook_size-1)<<14; } static const unsigned char MLOOP_1[64]={ @@ -180,8 +174,6 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln, #else ogg_uint32_t nextbark=MULT31(imap>>1,tBnyq1); #endif - /* nextbark is guaranteed to be less than 54 << 14 here and that ensures index - to barklook can at max be 53 and 54 here */ int nextf=barklook[nextbark>>14]+(((nextbark&0x3fff)* (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14); @@ -348,8 +340,6 @@ void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln, #else nextbark=MULT31((map+1)*(imap>>1),tBnyq1); #endif - /* nextbark is guaranteed to be less than 54 << 14 here and that ensures index - to barklook can at max be 53 and 54 here */ nextf=barklook[nextbark>>14]+ (((nextbark&0x3fff)* (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14); diff --git a/Tremolo/floor1ARM.s b/Tremolo/floor1ARM.s index c141399..981e86b 100644 --- a/Tremolo/floor1ARM.s +++ b/Tremolo/floor1ARM.s @@ -35,7 +35,6 @@ .text .global render_lineARM - .type render_lineARM, %function render_lineARM: @ r0 = n diff --git a/Tremolo/floor1LARM.s b/Tremolo/floor1LARM.s index 6f7f679..48b794c 100644 --- a/Tremolo/floor1LARM.s +++ b/Tremolo/floor1LARM.s @@ -35,7 +35,6 @@ .text .global render_lineARM - .type render_lineARM, %function render_lineARM: @ r0 = n diff --git a/Tremolo/mdct.c b/Tremolo/mdct.c index 4ea2cf1..1e4f44c 100644 --- a/Tremolo/mdct.c +++ b/Tremolo/mdct.c @@ -196,8 +196,6 @@ STIN void mdct_butterfly_32(DATA_TYPE *x){ mdct_butterfly_16(x+16); } -/* Ignoring overflows as the butterfly dct function expects and uses the overflows */ -__attribute__((no_sanitize("signed-integer-overflow"))) /* N/stage point generic N stage butterfly (in place, 2 register) */ STIN void mdct_butterfly_generic(DATA_TYPE *x,int points,int step){ LOOKUP_T *T = sincos_lookup0; diff --git a/Tremolo/mdctARM.s b/Tremolo/mdctARM.s index c16c5e9..0fcc68e 100644 --- a/Tremolo/mdctARM.s +++ b/Tremolo/mdctARM.s @@ -43,26 +43,11 @@ .global mdct_unroll_part3 .global mdct_unroll_postlap - .type mdct_backwardARM, %function - .type mdct_shift_right, %function - .type mdct_unroll_prelap, %function - .type mdct_unroll_part2, %function - .type mdct_unroll_part3, %function - .type mdct_unroll_postlap, %function - .extern sincos_lookup0 .extern sincos_lookup1 .hidden sincos_lookup0 .hidden sincos_lookup1 - @ clang doesn't support ADRL. - @ Workaround based on that at https://bugs.llvm.org/show_bug.cgi?id=24350. - .macro ADRL reg:req, label:req - add \reg, pc, #((\label - .L_adrl_\@) & 0xff00) - add \reg, \reg, #((\label - .L_adrl_\@) - ((\label - .L_adrl_\@) & 0xff00)) - .L_adrl_\@: - .endm - mdct_unroll_prelap: @ r0 = out @ r1 = post diff --git a/Tremolo/mdctLARM.s b/Tremolo/mdctLARM.s index 251bd1e..72a4647 100644 --- a/Tremolo/mdctLARM.s +++ b/Tremolo/mdctLARM.s @@ -43,13 +43,6 @@ .global mdct_unroll_part3 .global mdct_unroll_postlap - .type mdct_backwardARM, %function - .type mdct_shift_right, %function - .type mdct_unroll_prelap, %function - .type mdct_unroll_part2, %function - .type mdct_unroll_part3, %function - .type mdct_unroll_postlap, %function - .extern sincos_lookup0 .extern sincos_lookup1 diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp deleted file mode 100644 index f5e9968..0000000 --- a/fuzzer/Android.bp +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ***************************************************************************** - * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore - */ - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "external_tremolo_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["external_tremolo_license"], -} - -cc_fuzz { - name: "vorbis_dec_fuzzer", - host_supported: true, - srcs: [ - "vorbis_dec_fuzzer.cpp", - ], - static_libs: [ - "libvorbisidec", - "liblog", - ], - fuzz_config: { - cc: [ - "android-media-fuzzing-reports@google.com", - ], - componentid: 155276, - }, -} diff --git a/fuzzer/README.md b/fuzzer/README.md deleted file mode 100644 index f150072..0000000 --- a/fuzzer/README.md +++ /dev/null @@ -1,49 +0,0 @@ -# Fuzzer for libvorbis decoder -## Plugin Design Considerations -The fuzzer plugin for Vorbis is designed based on the understanding of the -codec and tries to achieve the following: - -##### Maximize code coverage -Dict file (dictionary file) is created for vorbis to ensure that the required start -bytes are present in every input file that goes to the fuzzer. -This ensures that decoder does not reject any input file in the first check - -##### Maximize utilization of input data -The plugin feeds the entire input data to the codec in a loop till the desired headers -(`01vorbis`, `05vorbis`) are parsed. -After that, the remaining data is passed at once to the decoder. -FrameSize in Vorbis is determined only after the call to extractor, so in absence of call to extractor, -we feed the entire remaining data to the decoder. - -This ensures that the plugin tolerates any kind of input (empty, huge, malformed, etc) -and doesnt `exit()` on any input and thereby increasing the chance of identifying vulnerabilities. - -## Build - -This describes steps to build vorbis_dec_fuzzer binary. - -### Android - -#### Steps to build -Build the fuzzer -``` - $ mm -j$(nproc) vorbis_dec_fuzzer -``` - -#### Steps to run -Create a directory CORPUS_DIR and copy some vorbis files to that folder -Push this directory to device. - -To run on device -``` - $ adb sync data - $ adb shell /data/fuzz/arm64/vorbis_dec_fuzzer/vorbis_dec_fuzzer CORPUS_DIR -``` -To run on host -``` - $ $ANDROID_HOST_OUT/fuzz/x86_64/vorbis_dec_fuzzer/vorbis_dec_fuzzer CORPUS_DIR -``` - -## References: - * http://llvm.org/docs/LibFuzzer.html - * https://github.com/google/oss-fuzz diff --git a/fuzzer/vorbis_dec_fuzzer.cpp b/fuzzer/vorbis_dec_fuzzer.cpp deleted file mode 100644 index 5c0e4c9..0000000 --- a/fuzzer/vorbis_dec_fuzzer.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - ***************************************************************************** - * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore - */ - -#include <stdint.h> -#include <string.h> -extern "C" { -#include <Tremolo/codec_internal.h> - -int _vorbis_unpack_books(vorbis_info *vi, oggpack_buffer *opb); -int _vorbis_unpack_info(vorbis_info *vi, oggpack_buffer *opb); -int _vorbis_unpack_comment(vorbis_comment *vc, oggpack_buffer *opb); -} - -constexpr int16_t kMaxNumSamplesPerChannel = 8192; -constexpr size_t kVorbisHeaderlength = 7; - -class Codec { - public: - Codec() = default; - ~Codec() { deInitDecoder(); } - bool initDecoder(); - void decodeFrames(const uint8_t *data, size_t size); - void deInitDecoder(); - - private: - bool mInfoUnpacked = false; - bool mBooksUnpacked = false; - int32_t mNumFramesLeftOnPage = -1; - vorbis_dsp_state *mState = nullptr; - vorbis_info *mVi = nullptr; -}; - -bool Codec::initDecoder() { - mVi = new vorbis_info{}; - if (!mVi) { - return false; - } - vorbis_info_clear(mVi); - - mState = new vorbis_dsp_state{}; - if (!mState) { - return false; - } - vorbis_dsp_clear(mState); - - mNumFramesLeftOnPage = -1; - mInfoUnpacked = false; - mBooksUnpacked = false; - - return true; -} - -static void makeBitReader(const uint8_t *data, size_t size, ogg_buffer *buf, ogg_reference *ref, - oggpack_buffer *bits) { - buf->data = const_cast<uint8_t *>(data); - buf->size = size; - buf->refcount = 1; - buf->ptr.owner = nullptr; - - ref->buffer = buf; - ref->begin = 0; - ref->length = size; - ref->next = nullptr; - - oggpack_readinit(bits, ref); -} - -void Codec::decodeFrames(const uint8_t *data, size_t size) { - /* Decode vorbis headers only once */ - while (size > 0) { - if (size > kVorbisHeaderlength && (!memcmp(&data[1], "vorbis", 6)) && - (!mInfoUnpacked || !mBooksUnpacked)) { - if ((data[0] == 1) || (data[0] == 5)) { - ogg_buffer buf; - ogg_reference ref; - oggpack_buffer bits; - /* skip kVorbisHeaderlength <type + "vorbis"> bytes */ - makeBitReader(data + kVorbisHeaderlength, size - kVorbisHeaderlength, &buf, &ref, &bits); - if (data[0] == 1) { - // release any memory that vorbis_info_init will blindly overwrite - vorbis_info_clear(mVi); - vorbis_info_init(mVi); - if (0 != _vorbis_unpack_info(mVi, &bits)) { - return; - } - mInfoUnpacked = true; - } else { /* data[0] == 5*/ - if (!mInfoUnpacked) { - return; - } - if (0 != _vorbis_unpack_books(mVi, &bits)) { - return; - } - // release any memory that vorbis_dsp_init will blindly overwrite - vorbis_dsp_clear(mState); - if (0 != vorbis_dsp_init(mState, mVi)) { - return; - } - mBooksUnpacked = true; - data += kVorbisHeaderlength; - size -= kVorbisHeaderlength; - break; - } - } - } - ++data; - --size; - } - - if (!mInfoUnpacked || !mBooksUnpacked) { - return; - } - - int32_t numPageFrames = 0; - if (size < sizeof(numPageFrames)) { - return; - } - memcpy(&numPageFrames, data + size - sizeof(numPageFrames), sizeof(numPageFrames)); - size -= sizeof(numPageFrames); - if (numPageFrames >= 0) { - mNumFramesLeftOnPage = numPageFrames; - } - - ogg_buffer buf; - buf.data = const_cast<unsigned char *>(data); - buf.size = size; - buf.refcount = 1; - buf.ptr.owner = nullptr; - - ogg_reference ref; - ref.buffer = &buf; - ref.begin = 0; - ref.length = buf.size; - ref.next = nullptr; - - ogg_packet pack; - pack.packet = &ref; - pack.bytes = ref.length; - pack.b_o_s = 0; - pack.e_o_s = 0; - pack.granulepos = 0; - pack.packetno = 0; - - int ret = vorbis_dsp_synthesis(mState, &pack, 1); - if (0 == ret) { - size_t maxSamplesInBuffer = kMaxNumSamplesPerChannel * mVi->channels; - size_t outCapacity = maxSamplesInBuffer * sizeof(int16_t); - int16_t outputBuf[outCapacity]; - vorbis_dsp_pcmout(mState, outputBuf, kMaxNumSamplesPerChannel); - } -} - -void Codec::deInitDecoder() { - if (mState) { - vorbis_dsp_clear(mState); - delete mState; - mState = nullptr; - } - - if (mVi) { - vorbis_info_clear(mVi); - delete mVi; - mVi = nullptr; - } -} - -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - if (size < kVorbisHeaderlength + 1) { /* 7 bytes for header , at least 1 byte for data */ - return 0; - } - Codec *codec = new Codec(); - if (!codec) { - return 0; - } - if (codec->initDecoder()) { - codec->decodeFrames(data, size); - } - delete codec; - return 0; -} diff --git a/fuzzer/vorbis_dec_fuzzer.dict b/fuzzer/vorbis_dec_fuzzer.dict deleted file mode 100644 index 290bdc6..0000000 --- a/fuzzer/vorbis_dec_fuzzer.dict +++ /dev/null @@ -1,5 +0,0 @@ -# Start code (bytes 0-6) -# The below 7 bytes correspond to byte containing value 01, followed by the 6 bytes of "vorbis" -kw1="\x01\x76\x6F\x72\x62\x69\x73" -# The below 7 bytes correspond to byte containing value 05, followed by the 6 bytes of "vorbis" -kw2="\x05\x76\x6F\x72\x62\x69\x73" diff --git a/tests/Android.bp b/tests/Android.bp index 28bf8a0..a27c234 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -1,19 +1,15 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "external_tremolo_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["external_tremolo_license"], -} - cc_test { - name: "VorbisDecoderTest", + name: "oob_oggpack_look", gtest: true, test_suites: ["device-tests"], - srcs: [ - "VorbisDecoderTest.cpp", + srcs: ["test_floor0.cpp"], + + // compile_multilib: "64", + + static_libs: [ + "libvorbisidec", + "liblog", ], shared_libs: [ @@ -21,20 +17,18 @@ cc_test { "liblog", ], - static_libs: [ - "libvorbisidec", - ], - cflags: [ - "-Werror", "-Wall", + "-Werror", ], sanitize: { - misc_undefined: [ - "unsigned-integer-overflow", - "signed-integer-overflow", - ], - cfi: true, + integer_overflow: true, + misc_undefined: ["bounds"], + diag: { + integer_overflow: true, + undefined: true, + misc_undefined: ["bounds"], + }, }, } diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml deleted file mode 100644 index cb81d5f..0000000 --- a/tests/AndroidTest.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2020 The Android Open Source Project - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---> -<configuration description="Test module config for vorbis decoder unit test"> - <option name="test-suite-tag" value="VorbisDecoderTest" /> - <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"> - <option name="cleanup" value="true" /> - <option name="push" value="VorbisDecoderTest->/data/local/tmp/VorbisDecoderTest" /> - <option name="push-file" - key="https://storage.googleapis.com/android_media/external/tremolo/tests/VorbisDecoderRes-1.0.zip?unzip=true" - value="/data/local/tmp/VorbisDecoderTestRes/" /> - </target_preparer> - <test class="com.android.tradefed.testtype.GTest" > - <option name="native-test-device-path" value="/data/local/tmp" /> - <option name="module-name" value="VorbisDecoderTest" /> - <option name="native-test-flag" value="-P /data/local/tmp/VorbisDecoderTestRes/" /> - <option name="native-test-flag" value="-C true" /> - </test> -</configuration> diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 8eb17cd..0000000 --- a/tests/README.md +++ /dev/null @@ -1,39 +0,0 @@ -## Media Testing ## ---- -#### Vorbis Decoder -The VorbisDecoder Test Suite validates the libvorbisidec library available in external/tremelo. - -Run the following steps to build the test suite: -``` -m VorbisDecoderTest -``` - -The 32-bit binaries will be created in the following path : ${OUT}/data/nativetest/ - -The 64-bit binaries will be created in the following path : ${OUT}/data/nativetest64/ - -To test 64-bit binary push binaries from nativetest64. -``` -adb push ${OUT}/data/nativetest64/VorbisDecoderTest/VorbisDecoderTest /data/local/tmp/ -``` - -To test 32-bit binary push binaries from nativetest. -``` -adb push ${OUT}/data/nativetest/VorbisDecoderTest/VorbisDecoderTest /data/local/tmp/ -``` - -The resource file for the tests is taken from [here](https://storage.googleapis.com/android_media/external/tremolo/tests/VorbisDecoderRes-1.0.zip). Download, unzip and push these files into device for testing. - -``` -adb push VorbisDecoderTestRes /data/local/tmp/ -``` - -usage: VorbisDecoderTest -P \<path_to_folder\> -C <remove_output_file> -``` -adb shell /data/local/tmp/VorbisDecoderTest -P /data/local/tmp/VorbisDecoderTestRes/ -C true -``` -Alternatively, the test can also be run using atest command. - -``` -atest VorbisDecoderTest -- --enable-module-dynamic-download=true -``` diff --git a/tests/VorbisDecoderTest.cpp b/tests/VorbisDecoderTest.cpp deleted file mode 100644 index 22e19a6..0000000 --- a/tests/VorbisDecoderTest.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -//#define LOG_NDEBUG 0 -#define LOG_TAG "VorbisDecoderTest" -#include <utils/Log.h> - -#include <fstream> - -#include "VorbisDecoderTestEnvironment.h" - -#define OUTPUT_FILE_NAME "/data/local/tmp/VorbisDecoderOutput.raw" - -constexpr uint32_t kMaxChannels = 255; -constexpr uint32_t kMaxNumSamplesPerChannel = 8192; - -struct vorbis_dsp_state; -struct vorbis_info; -struct FrameInfo { - int32_t bytesCount; - uint32_t flags; - int64_t timestamp; -}; - -extern "C" { - #include <Tremolo/codec_internal.h> - - int _vorbis_unpack_books(vorbis_info* vi, oggpack_buffer* opb); - int _vorbis_unpack_info(vorbis_info* vi, oggpack_buffer* opb); - int _vorbis_unpack_comment(vorbis_comment* vc, oggpack_buffer* opb); -} - -static VorbisDecoderTestEnvironment* gEnv = nullptr; - -class VorbisDecoderTest : public ::testing::TestWithParam<pair<string, string>> { - public: - VorbisDecoderTest() - : mNumFramesLeftOnPage(-1), - mInfoUnpacked(false), - mBooksUnpacked(false), - mInputBuffer(nullptr), - mOutputBuffer(nullptr), - mState(nullptr), - mVi(nullptr) {} - - ~VorbisDecoderTest() { - if (mInputBuffer) free(mInputBuffer); - if (mOutputBuffer) free(mOutputBuffer); - if (mEleStream.is_open()) mEleStream.close(); - if (mState) { - vorbis_dsp_clear(mState); - delete mState; - mState = nullptr; - } - - if (mVi) { - vorbis_info_clear(mVi); - delete mVi; - mVi = nullptr; - } - mNumFramesLeftOnPage = -1; - if (gEnv->cleanUp()) remove(OUTPUT_FILE_NAME); - } - - int32_t initVorbisDecoder(); - void processVorbisDecoder(vector<FrameInfo> Info, int32_t offset, int32_t range, - ofstream& ostrm); - - ifstream mEleStream; - int32_t mNumFramesLeftOnPage; - bool mInfoUnpacked; - bool mBooksUnpacked; - char* mInputBuffer; - int16_t* mOutputBuffer; - vorbis_dsp_state* mState; - vorbis_info* mVi; -}; - -void getInfo(string infoFileName, vector<FrameInfo>& Info) { - ifstream eleInfo; - eleInfo.open(infoFileName); - ASSERT_EQ(eleInfo.is_open(), true) << "Failed to open " << infoFileName; - while (1) { - int32_t bytesCount = 0; - uint32_t flags = 0; - uint32_t timestamp = 0; - - if (!(eleInfo >> bytesCount)) break; - eleInfo >> flags; - eleInfo >> timestamp; - Info.push_back({bytesCount, flags, timestamp}); - } - if (eleInfo.is_open()) eleInfo.close(); -} - -int32_t VorbisDecoderTest::initVorbisDecoder() { - if (!mVi) { - mVi = new vorbis_info{}; - if (!mVi) return -1; - } - vorbis_info_clear(mVi); - - if (!mState) { - mState = new vorbis_dsp_state{}; - if (!mState) return -1; - } - vorbis_dsp_clear(mState); - - return 0; -} - -static void makeBitReader(const void* inputBuffer, size_t size, ogg_buffer* buf, ogg_reference* ref, - oggpack_buffer* bits) { - buf->data = (uint8_t*)inputBuffer; - buf->size = size; - buf->refcount = 1; - buf->ptr.owner = nullptr; - - ref->buffer = buf; - ref->begin = 0; - ref->length = size; - ref->next = nullptr; - - oggpack_readinit(bits, ref); -} - -void VorbisDecoderTest::processVorbisDecoder(vector<FrameInfo> Info, int32_t offset, int32_t range, - ofstream& ostrm) { - int32_t frameID = offset; - ASSERT_GE(range, 0) << "Invalid Range"; - ASSERT_GE(offset, 0) << "Invalid Offset"; - ASSERT_LT(offset, Info.size()) << "Offset must be less than "; - - while (1) { - if (frameID == Info.size() || frameID == (offset + range)) break; - int32_t size = (Info)[frameID].bytesCount; - ASSERT_GE(size, 0) << "Size for the memory allocation is negative" << size; - - if (!mInputBuffer) { - mInputBuffer = (char*)malloc(size); - ASSERT_NE(mInputBuffer, nullptr) << "Insufficient memory to read frame"; - } - - mEleStream.read(mInputBuffer, size); - ASSERT_EQ(mEleStream.gcount(), size) - << "Invalid size read. Requested: " << size << " and read: " << mEleStream.gcount(); - - int32_t numChannels = mVi->channels; - /* Decode vorbis headers only once */ - if (size > 7 && !memcmp(&mInputBuffer[1], "vorbis", 6) && - (!mInfoUnpacked || !mBooksUnpacked)) { - ASSERT_TRUE((mInputBuffer[0] == 1) || (mInputBuffer[0] == 5)) - << "unexpected type received " << mInputBuffer[0]; - ogg_buffer buf; - ogg_reference ref; - oggpack_buffer bits; - - // skip 7 <type + "vorbis"> bytes - makeBitReader((const uint8_t*)mInputBuffer + 7, size - 7, &buf, &ref, &bits); - if (mInputBuffer[0] == 1) { - vorbis_info_init(mVi); - int32_t status = _vorbis_unpack_info(mVi, &bits); - ASSERT_EQ(status, 0) << "Encountered error while unpacking info"; - if (mVi->channels != numChannels) { - ALOGV("num channels changed: %d, sample rate: %ld", mVi->channels, mVi->rate); - numChannels = mVi->channels; - } - ASSERT_FALSE(numChannels < 1 || numChannels > kMaxChannels) - << "Invalid number of channels: " << numChannels; - mInfoUnpacked = true; - } else { - ASSERT_TRUE(mInfoUnpacked) << "Data with type:5 sent before sending type:1"; - int32_t status = _vorbis_unpack_books(mVi, &bits); - ASSERT_EQ(status, 0) << "Encountered error while unpacking books"; - status = vorbis_dsp_init(mState, mVi); - ASSERT_EQ(status, 0) << "Encountered error while dsp init"; - mBooksUnpacked = true; - } - ALOGV("frameID= %d", frameID); - frameID++; - free(mInputBuffer); - mInputBuffer = nullptr; - continue; - } - - ASSERT_TRUE(mInfoUnpacked && mBooksUnpacked) - << "Missing CODEC_CONFIG data mInfoUnpacked: " << mInfoUnpacked - << " mBooksUnpack: " << mBooksUnpacked; - - int32_t numPageFrames = 0; - ASSERT_GE(size, sizeof(numPageFrames)) - << "input header has size: " << size << " expected: " << sizeof(numPageFrames); - memcpy(&numPageFrames, mInputBuffer + size - sizeof(numPageFrames), sizeof(numPageFrames)); - size -= sizeof(numPageFrames); - if (numPageFrames >= 0) { - mNumFramesLeftOnPage = numPageFrames; - } - - ogg_buffer buf; - buf.data = reinterpret_cast<unsigned char*>(mInputBuffer); - buf.size = size; - buf.refcount = 1; - buf.ptr.owner = nullptr; - - ogg_reference ref; - ref.buffer = &buf; - ref.begin = 0; - ref.length = buf.size; - ref.next = nullptr; - - ogg_packet pack; - pack.packet = &ref; - pack.bytes = ref.length; - pack.b_o_s = 0; - pack.e_o_s = 0; - pack.granulepos = 0; - pack.packetno = 0; - - size_t outCapacity = kMaxNumSamplesPerChannel * numChannels * sizeof(int16_t); - if (!mOutputBuffer) { - mOutputBuffer = (int16_t*)malloc(outCapacity); - ASSERT_NE(mOutputBuffer, nullptr) << "Insufficient memory"; - } - - int32_t numFrames = 0; - int32_t ret = vorbis_dsp_synthesis(mState, &pack, 1); - if (0 != ret) { - ALOGV("vorbis_dsp_synthesis returned %d; ignored", ret); - } else { - numFrames = vorbis_dsp_pcmout(mState, mOutputBuffer, kMaxNumSamplesPerChannel); - if (numFrames < 0) { - ALOGV("vorbis_dsp_pcmout returned %d", numFrames); - numFrames = 0; - } - } - - if (mNumFramesLeftOnPage >= 0) { - if (numFrames > mNumFramesLeftOnPage) { - ALOGV("discarding %d frames at end of page", numFrames - mNumFramesLeftOnPage); - numFrames = mNumFramesLeftOnPage; - } - mNumFramesLeftOnPage -= numFrames; - } - if (numFrames) { - int32_t outSize = numFrames * sizeof(int16_t) * numChannels; - ostrm.write(reinterpret_cast<char*>(mOutputBuffer), outSize); - } - frameID++; - free(mInputBuffer); - mInputBuffer = nullptr; - } - ALOGV("Last frame decoded = %d", frameID); -} - -TEST_P(VorbisDecoderTest, FlushTest) { - string inputFileName = gEnv->getRes() + GetParam().first; - string infoFileName = gEnv->getRes() + GetParam().second; - - vector<FrameInfo> Info; - ASSERT_NO_FATAL_FAILURE(getInfo(infoFileName, Info)); - - mEleStream.open(inputFileName, ifstream::binary); - ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open " << inputFileName; - - ofstream ostrm; - ostrm.open(OUTPUT_FILE_NAME, std::ofstream::binary); - ASSERT_EQ(ostrm.is_open(), true) << "Failed to open " << OUTPUT_FILE_NAME; - - int32_t err = initVorbisDecoder(); - ASSERT_EQ(err, 0) << "initVorbisDecoder: failed to create decoder " << err; - - ASSERT_NO_FATAL_FAILURE(processVorbisDecoder(Info, 0, Info.size() / 3, ostrm)); - - // flushing the decoder - mNumFramesLeftOnPage = -1; - int32_t status = vorbis_dsp_restart(mState); - ASSERT_EQ(status, 0) << "Encountered error while restarting"; - - ASSERT_NO_FATAL_FAILURE(processVorbisDecoder(Info, (Info.size() / 3), Info.size(), ostrm)); - - ostrm.close(); - Info.clear(); -} - -TEST_P(VorbisDecoderTest, DecodeTest) { - string inputFileName = gEnv->getRes() + GetParam().first; - string infoFileName = gEnv->getRes() + GetParam().second; - - vector<FrameInfo> Info; - ASSERT_NO_FATAL_FAILURE(getInfo(infoFileName, Info)); - - mEleStream.open(inputFileName, ifstream::binary); - ASSERT_EQ(mEleStream.is_open(), true) << "Failed to open " << inputFileName; - - ofstream ostrm; - ostrm.open(OUTPUT_FILE_NAME, std::ofstream::binary); - ASSERT_EQ(ostrm.is_open(), true) << "Failed to open " << OUTPUT_FILE_NAME; - - int32_t err = initVorbisDecoder(); - ASSERT_EQ(err, 0) << "initVorbisDecoder: failed to create decoder " << err; - - ASSERT_NO_FATAL_FAILURE(processVorbisDecoder(Info, 0, Info.size(), ostrm)); - ostrm.close(); - Info.clear(); -} - -INSTANTIATE_TEST_SUITE_P( - VorbisDecoderTestAll, VorbisDecoderTest, - ::testing::Values(make_pair("bbb_vorbis_mono_64kbps_48000hz.vorbis", - "bbb_vorbis_mono_64kbps_48000hz.info"), - make_pair("bbb_vorbis_stereo_128kbps_44100hz_crypt.vorbis", - "bbb_vorbis_stereo_128kbps_44100hz_crypt.info"), - make_pair("bbb_vorbis_stereo_128kbps_48000hz.vorbis", - "bbb_vorbis_stereo_128kbps_48000hz.info"), - make_pair("bbb_vorbis_5ch_320kbps_48000hz.vorbis", - "bbb_vorbis_5ch_320kbps_48000hz.info"), - make_pair("bbb_vorbis_6ch_384kbps_24000hz.vorbis", - "bbb_vorbis_6ch_384kbps_24000hz.info"))); - -int main(int argc, char** argv) { - gEnv = new VorbisDecoderTestEnvironment(); - ::testing::AddGlobalTestEnvironment(gEnv); - ::testing::InitGoogleTest(&argc, argv); - int status = gEnv->initFromOptions(argc, argv); - if (status == 0) { - status = RUN_ALL_TESTS(); - ALOGV("Vorbis Decoder Test Result = %d", status); - } - return status; -} diff --git a/tests/VorbisDecoderTestEnvironment.h b/tests/VorbisDecoderTestEnvironment.h deleted file mode 100644 index 8de7524..0000000 --- a/tests/VorbisDecoderTestEnvironment.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VORBIS_DECODER_TEST_ENVIRONMENT_H__ -#define __VORBIS_DECODER_TEST_ENVIRONMENT_H__ - -#include <gtest/gtest.h> - -#include <getopt.h> - -using namespace std; - -class VorbisDecoderTestEnvironment : public ::testing::Environment { - public: - VorbisDecoderTestEnvironment() : res("/data/local/tmp/"), deleteOutput(true) {} - - // Parses the command line arguments - int initFromOptions(int argc, char** argv); - - void setRes(const char* _res) { res = _res; } - - const string getRes() const { return res; } - - bool cleanUp() const { return deleteOutput; } - - private: - string res; - bool deleteOutput; -}; - -int VorbisDecoderTestEnvironment::initFromOptions(int argc, char** argv) { - static struct option options[] = {{"res", required_argument, 0, 'P'}, - {"cleanUp", optional_argument, 0, 'C'}, - {0, 0, 0, 0}}; - - while (true) { - int index = 0; - int c = getopt_long(argc, argv, "P:C:", options, &index); - if (c == -1) { - break; - } - - switch (c) { - case 'P': { - setRes(optarg); - break; - } - case 'C': - if (!strcmp(optarg, "false")) { - deleteOutput = false; - } - break; - default: - break; - } - } - - if (optind < argc) { - fprintf(stderr, - "unrecognized option: %s\n\n" - "usage: %s <gtest options> <test options>\n\n" - "test options are:\n\n" - "-P, --path: Resource files directory location\n", - argv[optind ?: 1], argv[0]); - return 2; - } - return 0; -} - -#endif // __VORBIS_DECODER_TEST_ENVIRONMENT_H__ diff --git a/tests/oob_oggpack_look/Android.bp b/tests/oob_oggpack_look/Android.bp deleted file mode 100644 index 5f7937f..0000000 --- a/tests/oob_oggpack_look/Android.bp +++ /dev/null @@ -1,43 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "external_tremolo_license" - // to get the below license kinds: - // SPDX-license-identifier-BSD - default_applicable_licenses: ["external_tremolo_license"], -} - -cc_test { - name: "oob_oggpack_look", - gtest: true, - test_suites: ["device-tests"], - - srcs: ["test_floor0.cpp"], - - // compile_multilib: "64", - - static_libs: [ - "libvorbisidec", - "liblog", - ], - - shared_libs: [ - "libutils", - "liblog", - ], - - cflags: [ - "-Wall", - "-Werror", - ], - - sanitize: { - integer_overflow: true, - misc_undefined: ["bounds"], - diag: { - integer_overflow: true, - undefined: true, - misc_undefined: ["bounds"], - }, - }, -} diff --git a/tests/oob_oggpack_look/test_floor0.cpp b/tests/test_floor0.cpp index a3a8eb3..a3a8eb3 100644 --- a/tests/oob_oggpack_look/test_floor0.cpp +++ b/tests/test_floor0.cpp |