summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Sparks <davidsparks@android.com>2009-08-25 18:01:18 -0700
committerDave Sparks <davidsparks@android.com>2009-08-25 18:01:18 -0700
commitf198281e8a0b62addc8f5304ba20983feda9f905 (patch)
tree568e82009b7d4e9f69435e8b1503ebdd8d5cb7c3
parent56c99cd2c2c1e6ab038dac5fced5b92ccf11ff6c (diff)
downloadandroid_external_sonivox-f198281e8a0b62addc8f5304ba20983feda9f905.tar.gz
android_external_sonivox-f198281e8a0b62addc8f5304ba20983feda9f905.tar.bz2
android_external_sonivox-f198281e8a0b62addc8f5304ba20983feda9f905.zip
Fix infinite loop issue with correctly formed, but useless iMelody files (bug 2068782).
It is possible to construct a legitimate iMelody file that consists of only control commands such as ledon, ledoff, etc. in an infinite loop. If there are no notes or rests in the file, the iMelody parser will spin in an infinite loop sucking as many CPU cycles as it can get. This fix ignores loops that contain no notes or rests since they make no sense. The controls will be processed, but the loop will only execute once.
-rw-r--r--arm-wt-22k/lib_src/eas_imelody.c11
-rw-r--r--arm-wt-22k/lib_src/eas_imelodydata.h1
2 files changed, 9 insertions, 3 deletions
diff --git a/arm-wt-22k/lib_src/eas_imelody.c b/arm-wt-22k/lib_src/eas_imelody.c
index bf4375f..05380e5 100644
--- a/arm-wt-22k/lib_src/eas_imelody.c
+++ b/arm-wt-22k/lib_src/eas_imelody.c
@@ -396,6 +396,9 @@ static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I
{
pData->repeatOffset = pData->startLine + (EAS_I32) pData->index;
+ /* save current time and check it later to make sure the loop isn't zero length */
+ pData->repeatTime = pData->time;
+
#ifdef _DEBUG_IMELODY
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "Repeat offset = %d\n", pData->repeatOffset); */ }
#endif
@@ -410,9 +413,11 @@ static EAS_RESULT IMY_Event (S_EAS_DATA *pEASData, EAS_VOID_PTR pInstData, EAS_I
#ifdef _DEBUG_IMELODY
{ /* dpp: EAS_ReportEx(_EAS_SEVERITY_DETAIL, "End repeat section, repeat offset = %d\n", pData->repeatOffset); */ }
#endif
- /* ignore invalid repeats */
- if (pData->repeatCount >= 0)
- {
+ /* ignore zero-length loops */
+ if (pData->repeatTime == pData->time) {
+ pData->repeatCount = -1;
+ pData->repeatOffset = -1;
+ } else if (pData->repeatCount >= 0) {
/* decrement repeat count (repeatCount == 0 means infinite loop) */
if (pData->repeatCount > 0)
diff --git a/arm-wt-22k/lib_src/eas_imelodydata.h b/arm-wt-22k/lib_src/eas_imelodydata.h
index 57c1ed0..17d03dc 100644
--- a/arm-wt-22k/lib_src/eas_imelodydata.h
+++ b/arm-wt-22k/lib_src/eas_imelodydata.h
@@ -56,6 +56,7 @@ typedef struct
EAS_I32 restTicks; /* ticks to rest after current note */
EAS_I32 startLine; /* file offset at start of line (for repeats) */
EAS_I32 repeatOffset; /* file offset to start of repeat section */
+ EAS_I32 repeatTime; /* time at start of repeat section */
S_METADATA_CB metadata; /* metadata callback */
EAS_I16 repeatCount; /* repeat counter */
EAS_U8 state; /* current state EAS_STATE_XXXX */