Search code examples
c++utf-8gtkbase64gtkmm

UTF-8 error in GtkTextView while decoding base64


I have been trying to figure this out for a few days now. All I am trying to do is decode a base64 string and add it to a Gtk::TextView. Below is the code:

txtbuffer_ = Gtk::TextBuffer::create();
txtview_.set_buffer(txtbuffer_);
const Glib::ustring str = Glib::Base64::decode("YmJi3A==");
txtbuffer_->set_text(str);

When I run the program I get the error:

Gtk-CRITICAL **: gtk_text_buffer_emit_insert: assertion 'g_utf8_validate (text, len, NULL)' failed

This error only occurs with Unicode characters. When the text is ASCII it all works fine. I have tried three different base64 decoders, I tried using std::string and Glib::ustring with all the different decoders. I also tried using the function Glib::locale_to_utf8(), but that gives me the error terminate called after throwing an instance of 'Glib::ConvertError'. And I tried using Glib::convert with the same error.

I know that Gtk::TextView can display Unicode because if I set the text to a string with Unicode it will display the text. I read that Gtk::TextView displays text in UTF-8, so I think my problem is that the decoded string is not coded in UTF-8, but I am not sure. So my question is how can I get Gtk::TextView to display the decoded base64?

Added note: I am using version 3.8 of Gtkmm

Tested using version 3.12, same error message

Minimal program:

//test.h

#ifndef TEST_H_
#define TEST_H_

#include <gtkmm.h>

class MainWindow : public Gtk::Window
{
public:
    MainWindow();
    virtual ~MainWindow();

protected:
    Gtk::Box box_main;
    Gtk::TextView txtview_;
    Glib::RefPtr<Gtk::TextBuffer> txtbuffer_;
};

#endif /* TEST_H_ */

//test.cpp

#include "test.h"

MainWindow::MainWindow()
{   
    Gtk::Window::add(box_main);

    box_main.pack_start(txtview_);

    txtbuffer_ = Gtk::TextBuffer::create();
    txtview_.set_buffer(txtbuffer_);
    const Glib::ustring str = Glib::Base64::decode("YmJi3A==");
    txtbuffer_->set_text(str);

    Gtk::Window::show_all_children();
}

MainWindow::~MainWindow()
{

}

//main.cpp

#include "test.h"

int main(int argc, char* argv[])
{
    Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "test.program");

    MainWindow mw;

    return app->run(mw);
}

Solution

  • The reason why it was not working was because the string that I encoded was not UTF-8. Thanks to: https://mail.gnome.org/archives/gtk-list/2014-April/msg00016.html. I found out that the encoding was ISO-8859-1. So there are 2 fixes kind of, first, first encode the string to utf8:

    const Glib::ustring str2 = Glib::Base64::encode("bbbÜ");
    

    or you have to figure out the original encoding of the string, so for me this worked:

    Glib::convert(base64_str, "UTF-8", "ISO-8859-1");