don't crash when empty or corrupt dict file passed in.

This commit is contained in:
Andy2 2011-11-11 18:29:26 -08:00
parent b334e688bb
commit 44c5500ab0

View file

@ -439,9 +439,9 @@ and_dictionary_destroy( DictionaryCtxt* dict )
XP_FREE( ctxt->super.mpool, ctxt->super.bitmaps ); XP_FREE( ctxt->super.mpool, ctxt->super.bitmaps );
} }
XP_FREE( ctxt->super.mpool, ctxt->super.faces ); XP_FREEP( ctxt->super.mpool, &ctxt->super.faces );
XP_FREE( ctxt->super.mpool, ctxt->super.facePtrs ); XP_FREEP( ctxt->super.mpool, &ctxt->super.facePtrs );
XP_FREE( ctxt->super.mpool, ctxt->super.countsAndValues ); XP_FREEP( ctxt->super.mpool, &ctxt->super.countsAndValues );
XP_FREEP( ctxt->super.mpool, &ctxt->super.name ); XP_FREEP( ctxt->super.mpool, &ctxt->super.name );
XP_FREEP( ctxt->super.mpool, &ctxt->super.langName ); XP_FREEP( ctxt->super.mpool, &ctxt->super.langName );
@ -456,7 +456,7 @@ and_dictionary_destroy( DictionaryCtxt* dict )
(*env)->DeleteGlobalRef( env, ctxt->byteArray ); (*env)->DeleteGlobalRef( env, ctxt->byteArray );
} }
XP_FREE( ctxt->super.mpool, ctxt ); XP_FREE( ctxt->super.mpool, ctxt );
} } /* and_dictionary_destroy */
jobject jobject
and_dictionary_getChars( JNIEnv* env, DictionaryCtxt* dict ) and_dictionary_getChars( JNIEnv* env, DictionaryCtxt* dict )
@ -524,49 +524,54 @@ DictionaryCtxt*
makeDict( MPFORMAL JNIEnv *env, JNIUtilCtxt* jniutil, jstring jname, makeDict( MPFORMAL JNIEnv *env, JNIUtilCtxt* jniutil, jstring jname,
jbyteArray jbytes, jstring jpath, jstring jlangname, jboolean check ) jbyteArray jbytes, jstring jpath, jstring jlangname, jboolean check )
{ {
AndDictionaryCtxt* anddict = (AndDictionaryCtxt*) jbyte* bytes = NULL;
and_dictionary_make_empty( MPPARM(mpool) env, jniutil ); jbyteArray byteArray = NULL;
off_t bytesSize = 0;
jsize len = 0;
if ( NULL == jpath ) { if ( NULL == jpath ) {
len = (*env)->GetArrayLength( env, jbytes ); bytesSize = (*env)->GetArrayLength( env, jbytes );
anddict->byteArray = (*env)->NewGlobalRef( env, jbytes ); byteArray = (*env)->NewGlobalRef( env, jbytes );
anddict->bytes = bytes = (*env)->GetByteArrayElements( env, byteArray, NULL );
(*env)->GetByteArrayElements( env, anddict->byteArray, NULL );
} else { } else {
XP_ASSERT( NULL == anddict->byteArray );
const char* path = (*env)->GetStringUTFChars( env, jpath, NULL ); const char* path = (*env)->GetStringUTFChars( env, jpath, NULL );
struct stat statbuf; struct stat statbuf;
if ( 0 == stat( path, &statbuf ) ) { if ( 0 == stat( path, &statbuf ) && 0 < statbuf.st_size ) {
int fd = open( path, O_RDONLY ); int fd = open( path, O_RDONLY );
if ( fd >= 0 ) { if ( fd >= 0 ) {
anddict->bytes = mmap( NULL, statbuf.st_size, void* ptr = mmap( NULL, statbuf.st_size, PROT_READ,
PROT_READ, MAP_PRIVATE, MAP_PRIVATE, fd, 0 );
fd, 0 );
close( fd ); close( fd );
if ( MAP_FAILED != ptr ) {
anddict->bytesSize = statbuf.st_size; bytes = ptr;
len = statbuf.st_size; bytesSize = statbuf.st_size;
XP_ASSERT( MAP_FAILED != anddict->bytes ); }
} }
} }
(*env)->ReleaseStringUTFChars( env, jpath, path ); (*env)->ReleaseStringUTFChars( env, jpath, path );
} }
anddict->super.destructor = and_dictionary_destroy; AndDictionaryCtxt* anddict = NULL;
if ( NULL != bytes ) {
anddict = (AndDictionaryCtxt*)
and_dictionary_make_empty( MPPARM(mpool) env, jniutil );
anddict->bytes = bytes;
anddict->byteArray = byteArray;
anddict->bytesSize = bytesSize;
/* copy the name */ anddict->super.destructor = and_dictionary_destroy;
anddict->super.name = getStringCopy( MPPARM(mpool) env, jname );
anddict->super.langName = getStringCopy( MPPARM(mpool) env, jlangname );
XP_U32 numEdges; /* copy the name */
XP_Bool parses = parseDict( anddict, (XP_U8*)anddict->bytes, anddict->super.name = getStringCopy( MPPARM(mpool) env, jname );
len, &numEdges ); anddict->super.langName = getStringCopy( MPPARM(mpool) env, jlangname );
if ( !parses || (check && !checkSanity( &anddict->super, numEdges ) ) ) {
and_dictionary_destroy( (DictionaryCtxt*)anddict ); XP_U32 numEdges;
anddict = NULL; XP_Bool parses = parseDict( anddict, (XP_U8*)anddict->bytes,
bytesSize, &numEdges );
if ( !parses || (check && !checkSanity( &anddict->super, numEdges ) ) ) {
and_dictionary_destroy( (DictionaryCtxt*)anddict );
anddict = NULL;
}
} }
return (DictionaryCtxt*)anddict; return (DictionaryCtxt*)anddict;