I've verified that the assistant is serving up the files, such as http://127.0.0.1:$port/static/fonts/glyphicons-halflings-regular.svg
I've verified that the files it's serving have the right content.
This seems to only leave the likely explanation that the android web browser doesn't support the technology bootstrap 3 is using for its icons. This is svg, plus ttf, plus Embedded OpenType and Web Open Font Format. (I suppose it uses different ones on different browsers.)
I'm surprised that bootstrap would be using web fonts technology if it's not supported on Android, or wouldn't have a fallback to the plain old image method old versions of bootstrap used.
I have found some bootstrap bugs about icons not showing up on Android, like this one https://github.com/twbs/bootstrap/issues/10106 ... but those are about specific icons not showing up due to unicode issues. Not about all icons failing to show up.
I don't think it's an issue with the Android browser. It happens with Chrome and Firefox on Android as well. Moreover, the icons still don't show up if open the Webapp running on Android over network from a desktop browser. Firebug doesn't even show the request that should load the font file (compare to the desktop version where it loads the woff file in Firefox). So I suspect the Web server behaves different somehow. Some weird blocking issue maybe?
Not sure if this is related but I noticed a strange behavior: If I try to download the font file in a new tab, it blocks until I refresh the tab running the webapp. Only seen on desktop Firefox. Doesn't happen in Chromium.
On Android, the webserver returns a broken bootstrap.css. It seems like some binary garbage is appended to the end of the css file that looks suspiciously like the content or some fragment of the font file "glyphicons-halflings-regular.eot". Reason unknown.
That looks right, in particular the size is the same as the number of bytes in the file.
Hmm.. To double-check, I edited the file so that the string containing the content of this file was defined in foo.
*Main> length foo
113023
This might be innocuous; there are some unicode characters in the string that encode to multiple bytes. OTOH, if you see exactly 8197 bytes of extra garbage appended, I think we have our culprit.
37da3d7b5dcfd328aee6a7a91508b02edf720bca should fix this problem. I've verified the truncation is not present in the spliced source; lack bandwidh to test the binary right now.
Ok it seems like the linebreak at the end of each javascript file (0x0a) is replaced by a null byte on android. This probably causes the browser not to accept it as javascript so it's not executed.
The evilspliced data for eg, bootstrap.js omits that last byte. So presumably we overflow one byte and find a null (if we're lucky..).
I checked the -ddump-splices output, and it omits that last newline!
\});\
\\
\})( jQuery );"#),
Indeed, ghc omits any number of trailing newlines in this display.
This is probably only recently a problem because of the wacky use of a unsafe bytestring + length that file-embed has started to do. Before, the newline was not included, but that's still valid JS.
So, one fix would be to have the EvilSplicer rewrite the unsafePackAddressLen back to a regular bytestring construction. But this would need some tricky parsing (need to find the end of the string to remove the # from it). Alternatively, could remove trailing newlines from all the static js and css files. (Luckily none of the other static files end in a newline, and ghc is careful to preserve ending NULs etc).
For now, I've removed the trailing newlines from the files.
I've verified that the assistant is serving up the files, such as http://127.0.0.1:$port/static/fonts/glyphicons-halflings-regular.svg
I've verified that the files it's serving have the right content.
This seems to only leave the likely explanation that the android web browser doesn't support the technology bootstrap 3 is using for its icons. This is svg, plus ttf, plus Embedded OpenType and Web Open Font Format. (I suppose it uses different ones on different browsers.)
I'm surprised that bootstrap would be using web fonts technology if it's not supported on Android, or wouldn't have a fallback to the plain old image method old versions of bootstrap used.
I have found some bootstrap bugs about icons not showing up on Android, like this one https://github.com/twbs/bootstrap/issues/10106 ... but those are about specific icons not showing up due to unicode issues. Not about all icons failing to show up.
I don't think it's an issue with the Android browser. It happens with Chrome and Firefox on Android as well. Moreover, the icons still don't show up if open the Webapp running on Android over network from a desktop browser. Firebug doesn't even show the request that should load the font file (compare to the desktop version where it loads the woff file in Firefox). So I suspect the Web server behaves different somehow. Some weird blocking issue maybe?
Not sure if this is related but I noticed a strange behavior: If I try to download the font file in a new tab, it blocks until I refresh the tab running the webapp. Only seen on desktop Firefox. Doesn't happen in Chromium.
I checked the evilspliced tmp/androidtree/Assistant/WebApp/Types.hs, and the bootstrap.css there ends correctly, nothing weird appended.
The TH generated for this:
("css/bootstrap.css", GHC.IO.unsafePerformIO (Data.ByteString.Unsafe.unsafePackAddressLen 121220 file_content_omitted)That looks right, in particular the size is the same as the number of bytes in the file.
Hmm.. To double-check, I edited the file so that the string containing the content of this file was defined in foo.
This might be innocuous; there are some unicode characters in the string that encode to multiple bytes. OTOH, if you see exactly 8197 bytes of extra garbage appended, I think we have our culprit.
Seems to work! The icons show up on android now.
But JavaScript seems to be broken instead, dropdown menus don't work. Maybe more unwanted evil splicing in other files?
The evilspliced data for eg, bootstrap.js omits that last byte. So presumably we overflow one byte and find a null (if we're lucky..).
I checked the -ddump-splices output, and it omits that last newline!
\});\ \\ \})( jQuery );"#),Indeed, ghc omits any number of trailing newlines in this display.
This is probably only recently a problem because of the wacky use of a unsafe bytestring + length that file-embed has started to do. Before, the newline was not included, but that's still valid JS.
So, one fix would be to have the EvilSplicer rewrite the unsafePackAddressLen back to a regular bytestring construction. But this would need some tricky parsing (need to find the end of the string to remove the # from it). Alternatively, could remove trailing newlines from all the static js and css files. (Luckily none of the other static files end in a newline, and ghc is careful to preserve ending NULs etc).
For now, I've removed the trailing newlines from the files.