Description: Prevent unaligned memory access
Origin: upstream, https://github.com/chewing/libchewing/commit/71a55c08315be27ffc09114fb2f95ab284a0c379
Bug: https://github.com/chewing/libchewing/issues/53
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=709934
--- libchewing-0.3.4.orig/Makefile.am
+++ libchewing-0.3.4/Makefile.am
@@ -26,6 +26,7 @@ noinst_HEADERS =\
 	include/internal/choice-private.h \
 	include/internal/dict-private.h \
 	include/internal/global-private.h \
+	include/internal/memory-private.h \
 	include/internal/pinyin-private.h \
 	include/internal/hash-private.h \
 	include/internal/key2pho-private.h \
--- libchewing-0.3.4.orig/src/dict.c
+++ libchewing-0.3.4/src/dict.c
@@ -21,6 +21,7 @@
 #include "private.h"
 #include "plat_mmap.h"
 #include "dict-private.h"
+#include "memory-private.h"
 
 #if ! defined(USE_BINARY_DATA)
 static char *fgettab( char *buf, int maxlen, FILE *fp )
@@ -145,7 +146,7 @@ static void Str2Phrase( ChewingData *pgd
 	pgdata->static_data.dict_cur_pos = (unsigned char *)pgdata->static_data.dict_cur_pos + sizeof(unsigned char);
 	memcpy( phr_ptr->phrase, pgdata->static_data.dict_cur_pos, size );
 	pgdata->static_data.dict_cur_pos = (unsigned char *)pgdata->static_data.dict_cur_pos + size;
-	phr_ptr->freq = *(int *) pgdata->static_data.dict_cur_pos;
+	phr_ptr->freq = GetInt32(pgdata->static_data.dict_cur_pos);
 	pgdata->static_data.dict_cur_pos = (unsigned char *)pgdata->static_data.dict_cur_pos + sizeof(int);
 	phr_ptr->phrase[ size ] = '\0';
 #endif
--- libchewing-0.3.4.orig/src/hash.c
+++ libchewing-0.3.4/src/hash.c
@@ -25,6 +25,7 @@
 #include "hash-private.h"
 #include "private.h"
 #include "global.h"
+#include "memory-private.h"
 
 int AlcUserPhraseSeq( UserPhraseData *pData, int phonelen, int wordlen )
 {
@@ -148,8 +149,7 @@ static void HashItem2String( char *str,
 void HashItem2Binary( char *str, HASH_ITEM *pItem )
 {
 	int i, phraselen;
-	uint16_t *pshort;
-	unsigned char *puc;
+	char *pc;
 
 	memset( str, 0, FIELD_SIZE );
 	if ( sizeof(int) * 4 + ueStrLen( pItem->data.wordSeq ) * 2 +
@@ -159,25 +159,24 @@ void HashItem2Binary( char *str, HASH_IT
 	}
 
 	/* freq info */
-	*(int*) &str[ 0 ] = pItem->data.userfreq;
-	*(int*) &str[ 4 ] = pItem->data.recentTime;
-	*(int*) &str[ 8 ] = pItem->data.maxfreq;
-	*(int*) &str[ 12 ] = pItem->data.origfreq;
+	PutInt32( pItem->data.userfreq, &str[ 0 ] );
+	PutInt32( pItem->data.recentTime, &str[ 4 ] );
+	PutInt32( pItem->data.maxfreq, &str[ 8 ] );
+	PutInt32( pItem->data.origfreq, &str[ 12 ] );
 
 	/* phone seq*/
 	phraselen = ueStrLen( pItem->data.wordSeq );
 	str[ 16 ] = phraselen;
-	pshort = (uint16_t *) &str[ 17 ];
+	pc = &str[ 17 ];
 	for ( i = 0; i < phraselen; i++ ) {
-		*pshort = pItem->data.phoneSeq[ i ];
-		pshort++;
+		PutUint16( pItem->data.phoneSeq[ i ], pc );
+		pc += 2;
 	}
 
 	/* phrase */
-	puc = (unsigned char *) pshort;
-	*puc = strlen( pItem->data.wordSeq );
-	strcpy( (char *) (puc + 1), pItem->data.wordSeq );
-	pItem->data.wordSeq[ (int) *puc ] = '\0';
+	*pc = strlen( pItem->data.wordSeq );
+	strcpy( (pc + 1), pItem->data.wordSeq );
+	pItem->data.wordSeq[ (unsigned char) *pc ] = '\0';
 }
 
 void HashModify( ChewingData *pgdata, HASH_ITEM *pItem )
@@ -233,13 +232,6 @@ static int isValidChineseString( char *s
 	return 1;
 }
 
-static int ReadInt(unsigned char *addr)
-{
-	/* TODO: Use bit-wise operation to read */
-	int *p = (void*)addr;
-	return *p;
-}
-
 /**
  * @return 1, 0 or -1
  * retval 0	end of file
@@ -249,33 +241,30 @@ static int ReadInt(unsigned char *addr)
 int ReadHashItem_bin( const char *srcbuf, HASH_ITEM *pItem, int item_index )
 {
 	int len, i;
-	uint16_t *pshort;
-	unsigned char recbuf[ FIELD_SIZE ], *puc;
+	const char *pc;
 
-	memcpy( recbuf, srcbuf, FIELD_SIZE );
 	memset( pItem, 0, sizeof(HASH_ITEM) );
 
 	/* freq info */
-	pItem->data.userfreq	= ReadInt(&recbuf[ 0 ]);
-	pItem->data.recentTime	= ReadInt(&recbuf[ 4 ]);
-	pItem->data.maxfreq	= ReadInt(&recbuf[ 8 ]);
-	pItem->data.origfreq	= ReadInt(&recbuf[ 12 ]);
+	pItem->data.userfreq	= GetInt32(&srcbuf[ 0 ]);
+	pItem->data.recentTime	= GetInt32(&srcbuf[ 4 ]);
+	pItem->data.maxfreq	= GetInt32(&srcbuf[ 8 ]);
+	pItem->data.origfreq	= GetInt32(&srcbuf[ 12 ]);
 
 	/* phone seq, length in num of chi words */
-	len = (int) recbuf[ 16 ];
+	len = (int) srcbuf[ 16 ];
 	pItem->data.phoneSeq = ALC( uint16_t, len + 1 );
-	pshort = (uint16_t *) &recbuf[ 17 ];
+	pc = &srcbuf[ 17 ];
 	for ( i = 0; i < len; i++ ) {
-		pItem->data.phoneSeq[ i ] = *pshort;
-		++pshort;
+		pItem->data.phoneSeq[ i ] = GetUint16( pc );
+		pc += 2;
 	}
 	pItem->data.phoneSeq[ i ] = 0;
 
 	/* phrase, length in num of bytes */
-	puc = (unsigned char *) pshort;
-	pItem->data.wordSeq = ALC( char, (*puc) + 1 );
-	strcpy( pItem->data.wordSeq, (char *) (puc + 1) );
-	pItem->data.wordSeq[ (int) *puc ] = '\0';
+	pItem->data.wordSeq = ALC( char, (*pc) + 1 );
+	strcpy( pItem->data.wordSeq, (char *) (pc + 1) );
+	pItem->data.wordSeq[ (unsigned int) *pc ] = '\0';
 
 	/* Invalid UTF-8 Chinese characters found */
 	if ( ! isValidChineseString( pItem->data.wordSeq ) ) {
--- /dev/null
+++ libchewing-0.3.4/src/common/memory.c
@@ -0,0 +1,41 @@
+/**
+ * memory.c
+ *
+ * Copyright (c) 2013
+ *	libchewing Core Team. See ChangeLog for details.
+ *
+ * See the file "COPYING" for information on usage and redistribution
+ * of this file.
+ */
+#include "memory-private.h"
+
+#include <assert.h>
+#include <string.h>
+
+uint16_t GetUint16( const char *ptr )
+{
+	uint16_t val;
+	assert( ptr );
+	memcpy( &val, ptr, sizeof( val ) );
+	return val;
+}
+
+void PutUint16( uint16_t val, char *ptr )
+{
+	assert(ptr);
+	memcpy( ptr, &val, sizeof( val ) );
+}
+
+int GetInt32( const char *ptr )
+{
+	int val;
+	assert( ptr );
+	memcpy( &val, ptr, sizeof( val ) );
+	return val;
+}
+
+void PutInt32( int val, char *ptr )
+{
+	assert( ptr );
+	memcpy( ptr, &val, sizeof( val ) );
+}
--- libchewing-0.3.4.orig/src/common/Makefile.am
+++ libchewing-0.3.4/src/common/Makefile.am
@@ -9,4 +9,5 @@ noinst_LTLIBRARIES = libcommon.la
 libcommon_la_SOURCES = \
 	key2pho.c \
 	chewing-utf8-util.c \
+	memory.c \
 	$(NULL)
--- /dev/null
+++ libchewing-0.3.4/include/internal/memory-private.h
@@ -0,0 +1,25 @@
+/**
+ * memory-private.h
+ *
+ * Copyright (c) 2013
+ *	libchewing Core Team. See ChangeLog for details.
+ *
+ * See the file "COPYING" for information on usage and redistribution
+ * of this file.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#  include <inttypes.h>
+#elif defined HAVE_STDINT_H
+#  include <stdint.h>
+#endif
+
+uint16_t GetUint16( const char *ptr );
+void PutUint16( uint16_t val, char *ptr );
+
+int GetInt32( const char *ptr );
+void PutInt32( int val, char *ptr );
--- libchewing-0.3.4.orig/Makefile.in
+++ libchewing-0.3.4/Makefile.in
@@ -325,6 +325,7 @@ noinst_HEADERS = \
 	include/internal/choice-private.h \
 	include/internal/dict-private.h \
 	include/internal/global-private.h \
+	include/internal/memory-private.h \
 	include/internal/pinyin-private.h \
 	include/internal/hash-private.h \
 	include/internal/key2pho-private.h \
--- libchewing-0.3.4.orig/src/common/Makefile.in
+++ libchewing-0.3.4/src/common/Makefile.in
@@ -66,7 +66,7 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 libcommon_la_LIBADD =
-am_libcommon_la_OBJECTS = key2pho.lo chewing-utf8-util.lo
+am_libcommon_la_OBJECTS = key2pho.lo chewing-utf8-util.lo memory.lo
 libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -244,6 +244,7 @@ noinst_LTLIBRARIES = libcommon.la
 libcommon_la_SOURCES = \
 	key2pho.c \
 	chewing-utf8-util.c \
+	memory.c \
 	$(NULL)
 
 all: all-am
@@ -300,6 +301,7 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chewing-utf8-util.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/key2pho.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Plo@am__quote@
 
 .c.o:
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
