Menu ▾ ▴

#1358 Keepass crash on Mono/OpenSUSE with System.Text.DecoderFallbackException

KeePass_2.x
closed
nobody
None
5
2015-11-21
2015-03-25
No

Lost a lot of time the last days trying to get Keepass 2.28 to run on my OpenSUSE Linux box with mono. Keepass window opened correctly, but whenever I tried accessing a file (either open an existing or create a new one), it crashed with a "System.Text.DecoderFallbackException".

After trying a lot of Mono workarounds (as some old posts suggested Mono issues here), I finally found that it was trying to modify my ~/.recently-used file and expected an XML there. For any reason, this was a binary file on my system leading to the mentioned crash.

After removing the file, it worked well.

Could you please either fix this in Keepass or add an according note to http://keepass.info/help/v2/setup.html? Thanks!

Reproducing is easy:

# cd
# mv .recently-used .recently-used.sic
# cp /bin/bash .recently-used
# cd Keepass-dir
# mono KeePass.exe
# Click on icon to create new DB
System.Xml.XmlException: Invalid data ---> System.Text.DecoderFallbackException: Exception of type 'System.Text.DecoderFallbackException' was thrown.
  at System.Text.DecoderExceptionFallbackBuffer.Fallback (System.Byte[] bytesUnknown, Int32 index) [0x00000] in <filename unknown>:0 
  at System.Text.UTF8Encoding.Fallback (System.Object provider, System.Text.DecoderFallbackBuffer& buffer, System.Byte[]& bufferArg, System.Byte* bytes, Int64 byteIndex, UInt32 size, System.Char* chars, System.Int32& charIndex) [0x00000] in <filename unknown>:0 
  at System.Text.UTF8Encoding.InternalGetChars (System.Byte* bytes, Int32 byteCount, System.Char* chars, Int32 charCount, System.UInt32& leftOverBits, System.UInt32& leftOverCount, System.Object provider, System.Text.DecoderFallbackBuffer& fallbackBuffer, System.Byte[]& bufferArg, Boolean flush) [0x00000] in <filename unknown>:0 
  at System.Text.UTF8Encoding.InternalGetChars (System.Byte[] bytes, Int32 byteIndex, Int32 byteCount, System.Char[] chars, Int32 charIndex, System.UInt32& leftOverBits, System.UInt32& leftOverCount, System.Object provider, System.Text.DecoderFallbackBuffer& fallbackBuffer, System.Byte[]& bufferArg, Boolean flush) [0x00000] in <filename unknown>:0 
  at System.Text.UTF8Encoding+UTF8Decoder.GetChars (System.Byte[] bytes, Int32 byteIndex, Int32 byteCount, System.Char[] chars, Int32 charIndex) [0x00000] in <filename unknown>:0 
  at System.Xml.NonBlockingStreamReader.ReadBuffer () [0x00000] in <filename unknown>:0 
  at System.Xml.NonBlockingStreamReader.Read (System.Char[] dest_buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0 
  at System.Xml.XmlStreamReader.Read (System.Char[] dest_buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Xml.XmlStreamReader.Read (System.Char[] dest_buffer, Int32 index, Int32 count) [0x00000] in <filename unknown>:0 
  at Mono.Xml2.XmlTextReader.ReadTextReader (Int32 remained) [0x00000] in <filename unknown>:0 
  at Mono.Xml2.XmlTextReader.PeekChar () [0x00000] in <filename unknown>:0 
  at Mono.Xml2.XmlTextReader.ReadContent () [0x00000] in <filename unknown>:0 
  at Mono.Xml2.XmlTextReader.Read () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlTextReader.Read () [0x00000] in <filename unknown>:0 
  at Mono.Xml.EntityResolvingXmlReader.Read () [0x00000] in <filename unknown>:0 
  at Mono.Xml.DTDValidatingReader.ReadContent () [0x00000] in <filename unknown>:0 
  at Mono.Xml.DTDValidatingReader.Read () [0x00000] in <filename unknown>:0 
  at Mono.Xml.Schema.XsdValidatingReader.Read () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlValidatingReader.Read () [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDocument.ReadNodeCore (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDocument.ReadNode (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDocument.Load (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0 
  at System.Xml.XmlDocument.Load (System.String filename) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.UnixFileSystem.WriteRecentlyUsedFiles (System.String fileToAdd) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.MWFVFS.WriteRecentlyUsedFiles (System.String filename) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.MWFFileView.WriteRecentlyUsed (System.String fullfilename) [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) System.Windows.Forms.MWFFileView:WriteRecentlyUsed (string)
  at System.Windows.Forms.FileDialog.OnClickOpenSaveButton (System.Object sender, System.EventArgs e) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.Control.OnClick (System.EventArgs e) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.Button.OnClick (System.EventArgs e) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.ButtonBase.OnMouseUp (System.Windows.Forms.MouseEventArgs mevent) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.Button.OnMouseUp (System.Windows.Forms.MouseEventArgs mevent) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.Control.WmLButtonUp (System.Windows.Forms.Message& m) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.Control.WndProc (System.Windows.Forms.Message& m) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.ButtonBase.WndProc (System.Windows.Forms.Message& m) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.Button.WndProc (System.Windows.Forms.Message& m) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.Control+ControlWindowTarget.OnMessage (System.Windows.Forms.Message& m) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.Control+ControlNativeWindow.WndProc (System.Windows.Forms.Message& m) [0x00000] in <filename unknown>:0 
  at System.Windows.Forms.NativeWindow.WndProc (IntPtr hWnd, Msg msg, IntPtr wParam, IntPtr lParam) [0x00000] in <filename unknown>:0 

Discussion

  • Paul

    Paul - 2015-03-25

    Works fine on my Ubuntu x64.

    As the .recently-used file is not created by KeePass I can't see why KeePass should check it for validity.

    KeePass stores recently used file information in /usr/USER/.config/KeePass/KeePass.config.xml on my Ubuntu. Is that the file you are expecting?

    cheers, Paul

     
  • Gernot Hillier

    Gernot Hillier - 2015-03-25

    No, I'm exactly speaking about $HOME/.recently-used. In the working state, it looks like this:

    $ cat /home/gernot/.recently-used 
    <?xml version="1.0"?>
    <RecentFiles>
      <RecentItem>
        <URI>file:///home/gernot/<my-path>/keepass.kdbx</URI>
        <Mime-Type>application/x-keepass2</Mime-Type>
        <Timestamp>1427313002</Timestamp>
        <Groups />
      </RecentItem>
      <RecentItem>
        <URI>file:///home/gernot/NewDatabase.kdbx</URI>
        <Mime-Type>application/x-keepass2</Mime-Type>
        <Timestamp>1427227766</Timestamp>
        <Groups />
      </RecentItem>
      ...
    </RecentFiles>
    

    As you can see, all used Keepass databases will end up there. I also have /home/gernot/.config/KeePass/KeePass.config.xml, but this is completely different and did NOT cause my problem. I strace-d it and found that it crashed after accessing $HOME/.recently-used and could prove it by just removing that file.

    After a closer look to the backtrace above, I start to believe that this is an implementation detail of Mono. Likely, the FileDialog implementation internally uses this file on Linux to store file open history. As I've neither any clue about Mono internals nor about .NET programming, I'm not sure whether you can influence this in KeePass at all.

    So probably one should verify this with a small Mono test program and file another bug report with Mono folks...

    Nevertheless, it could help to add a small hint to the KeePass Setup page?

     
  • Paul

    Paul - 2015-03-25

    Looks like you had an unusual problem that is specific to OpenSUSE. Let us know if you have more problems or a solution.

    cheers, Paul

     
  • Dominik Reichl

    Dominik Reichl - 2015-03-29
    • status: open --> closed
     
  • David McNeill

    David McNeill - 2015-11-21

    It's not an OpenSUSE specific issue. It still occurs at KeePass 2.30 on Ubuntu 14.04

    It's the System.Xml component throwing an exception at a badly formed XML file.

    The KeePass app then surfaces the exception and crashes, rather than swallowing it and saying I don't care if the .recently-used file is XML invalid, and that being the case, I'll warn and ignore it.

    You can find the issue in the file with

    xmllint .recently-used
    

    In my case it was libreoffice not putting a closing tag at the end of the file, as it made a mess of the last entry. I deleted the last RecentItem block and added an end tag

    </RecentFiles>
    

    Now KeyPass can open, new and save files.

     
  • David McNeill

    David McNeill - 2015-11-21

    If KeePass can't tell mono to behave gracefully with a try-catch on the FileDialog, then it should pre-flight check the xml .recently-used file, and dialog offer options to fix it, delete it, rename it, or pause until it is manually fixed.

    This is a moderate impact bug, as it causes KeyPass to die on first-time use, when saving it's first database, when used on a machine for the first time that has a longtime invalid recently used file. This could cause new users to go ahh, garbage and move on to another app.

    It could also mean long-time keepass users suddenly can't access or save their database, through no fault of keepass, as any other app could mess up the shared recently-used file. This could cause stress if it's at a critical login time, such as a banking or physical access transaction.

     
  • Dominik Reichl

    Dominik Reichl - 2015-11-21

    The exception cannot simply be ignored using a try-catch, because then KeePass doesn't get the results (file names) of the FileDialog.

    I've now implemented the following: before showing a FileDialog, KeePass tries to load the file ~/.recently-used and deletes it, if it doesn't contain valid XML data. This behavior should be ok, as the file doesn't contain any important data anyway and other applications probably would have problems loading the file, too.

    Here's the latest KeePass development snapshot for testing:
    http://keepass.info/filepool/KeePass_151121.zip

    Thanks and best regards,
    Dominik

     

Log in to post a comment.