klausw / hackerskeyboard

Hacker's Keyboard (official)
https://play.google.com/store/apps/details?id=org.pocketworkstation.pckeyboard
Apache License 2.0
1.87k stars 443 forks source link

BinaryDictionary loads incomplete data? #125

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Reported by Michał Sapalski via email:

"I think I've found a bug in BinaryDictionary.java 
(BinaryDictionary.loadDictionary(InputStrem in[]) method). According to my 
knowledge, in java InputStream.available() sometimes returns less bytes than 
there is in the stream and in such cases dictionary won't be fully loaded. The 
problem is, that the bug will show only sometimes: it happened to me using both 
downloaded latest apk file and self-compiled code, but when I fixed the code it 
disappeared both from compiled and downloaded versions (I think that it might 
be because of some operating system optimization - Android learned that 
dictionary file is often loaded to memory)."

Patch attached, I'll take a look to see what's going on. At first glance your 
fix looks right, the available() method returns the size that can be read 
without blocking and it appears to have been used inappropriately. Thanks!

Original issue reported on code.google.com by Klaus.We...@gmail.com on 14 Dec 2011 at 7:05

Attachments:

GoogleCodeExporter commented 8 years ago
Hm, this is odd. Apparently the API sample content/ReadAsset also uses 
.available(). I dug around briefly in the Android source, and it looks as if it 
is supposed to return an exact size for asset-backed file descriptors.

See frameworks/base/core/java/android/content/res/AssetFileDescriptor.java, the 
AutoCloseInputStream uses .getLength() in its available() definition.

There is a known issue that Android versions older than 2.3 (Gingerbread) had a 
limit of 1MB for reading compressed assets. Is it possible that you switched 
emulator versions when testing? The bug would show errors like this:

  D/asset (909): Data exceeds UNCOMPRESS_DATA_MAX (1424000 vs 1048576)

Original comment by Klaus.We...@gmail.com on 22 Dec 2011 at 9:00

GoogleCodeExporter commented 8 years ago
This is strange, because when I was having this bug I changed the source to get 
more verbose logs (removed "if" in line 149 of BinaryDictionary.java) and 
definitely saw that all expected bytes (returned by available() method) were 
being read, but still it was only a part of the dictionary (less than 1000 
bytes). Something similar happened when I was using .apk version from downloads 
page (there was no line "Loaded dictionary len=something" in the logs and the 
dictionary wasn't working). But, as I mentioned before, I'm no longer able to 
reproduce the bug - both versions (compiled and from .apk) work now. I was 
testing it on a phone (Nexus One, Android 2.3.6), so maybe it was just a 
strange glitch of this particular model and it was just a coincidence that it 
started to work when I changed the sources according to my patch.

Original comment by sapalski...@gmail.com on 23 Dec 2011 at 4:29