From acaf622782072c9c373015889e181583ae13bbdc Mon Sep 17 00:00:00 2001 From: Volker Birk Date: Sun, 21 Feb 2016 21:44:32 +0100 Subject: [PATCH] redesign of system.db --- .hgignore | 2 + db/create_system_db.sql | 35 ++++++-- db/sort.py | 74 +++++++++++++++++ src/pEpEngine.c | 6 +- test/Makefile | 1 + test/msg4.asc | 172 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 280 insertions(+), 10 deletions(-) create mode 100644 db/sort.py create mode 100644 test/msg4.asc diff --git a/.hgignore b/.hgignore index be28ca12e..59b3e9227 100644 --- a/.hgignore +++ b/.hgignore @@ -13,6 +13,8 @@ Debug Release *.lib *.obj +.DS_Store +ws build-android/pEpEngine-android-1.zip build-android/third-party build-android/pEpEngine-android-1 diff --git a/db/create_system_db.sql b/db/create_system_db.sql index 9f79cdaff..0e2bb2bb2 100644 --- a/db/create_system_db.sql +++ b/db/create_system_db.sql @@ -1,17 +1,36 @@ +-- DDL + +CREATE TABLE i18n_language ( + lang text primary key, + name text +); + CREATE TABLE wordlist ( - lang text, - id integer, - word text, - entropy integer + lang text + references i18n_language (lang), + id integer, + word text, + entropy integer ); CREATE UNIQUE INDEX wordlist_pk on wordlist (lang, id); -CREATE TABLE i18n ( - lang text primary key, +CREATE TABLE i18n_token ( + lang text + references i18n_language (lang), + id integer, phrase text ); -INSERT INTO i18n VALUES ('en', 'I want to have this conversation in English language'); -INSERT INTO i18n VALUES ('de', 'Ich möchte diese Unterhaltung auf Deutsch führen'); +CREATE UNIQUE INDEX i18n_token_pk on i18n_token (lang, id); + +-- DML + +INSERT INTO i18n_language VALUES ('en', 'English'); +INSERT INTO i18n_token VALUES ('en', 1, 'I want to have this conversation in English language'); + +INSERT INTO i18n_language VALUES ('de', 'Deutsch'); +INSERT INTO i18n_token VALUES ('de', 1, 'Ich möchte dieses Gespräch auf Deutsch führen'); + -- add more languages here + diff --git a/db/sort.py b/db/sort.py new file mode 100644 index 000000000..689467a87 --- /dev/null +++ b/db/sort.py @@ -0,0 +1,74 @@ +#! /usr/bin/env python3 + +from argparse import ArgumentParser +from fileinput import FileInput, hook_encoded +import re, itertools, sys + +try: + from math import log2 +except: + from math import log + def log2(x): return log(x) / log(2) + +word = re.compile(r"(\S*?)(/|\s.*|$)") +unwanted = re.compile(r"(^\d|[^']*')") +space = re.compile(r'^\s') + +p = ArgumentParser(description="create dictionary csv out of hunspell data") +p.add_argument('--hunspell', '-H', type=str, default="/usr/share/hunspell", + help='directory where hunspell dictionary files reside (default: /usr/share/hunspell)') +p.add_argument('--lang', '-l', type=str, default="en_US", + help='use dictionary for language LANG (default: en_US)') +p.add_argument('--encoding', '-e', type=str, default="utf-8", + help='file encoding (default: utf-8)') +p.add_argument('--full', '-f', action='store_true', + help="full list - don't reduce to 65536 words") + +args = p.parse_args() + +try: + from icu import UnicodeString, Locale +except ImportError: + print("warning: PyICU not installed, using fallback", file=sys.stderr) + def upper(x): + return x.upper(); +else: + locale = Locale(args.lang) + def upper(x): + u = UnicodeString(x) + return str(u.toUpper(locale)) + +_all = ( + upper(word.match(line).group(1)) + for line in FileInput( + args.hunspell + "/" + args.lang + ".dic", + openhook=hook_encoded(args.encoding) + ) + if not space.match(line) +) +_words = [w for w in _all if len(w) > 2 and not unwanted.match(w)] +_words.sort() +_words = [w for w, g in itertools.groupby(_words)] + +if not args.full: + while len(_words) > 65536 * 2: + _words = _words[::2] + +if len(_words) > 65536: + if not args.full: + _words = _words[:65536] +elif len(_words) < 65536: + sys.stderr.write( + "warning for {}: only {:.2f} bit in wordlist, that makes {:.2f} bit for 5 words\n".format( + args.lang, + log2(len(_words)), + log2(len(_words))*5 + ) + ) + _words.extend(_words[:65536-len(_words)]) + +if not args.full: + assert len(_words) == 65536, "lenght is {}".format(len(_words)) + +for i, w in enumerate(_words): + print("{l},{i},{w},0".format(l=args.lang[:2], i=i, w=w)) diff --git a/src/pEpEngine.c b/src/pEpEngine.c index 8c74909d0..1505ed9f4 100644 --- a/src/pEpEngine.c +++ b/src/pEpEngine.c @@ -205,9 +205,11 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session) sql_least_trust = "select min(comm_type) from trust where pgp_keypair_fpr = ?1 ;"; - sql_mark_as_compromized = "update trust not indexed set comm_type = 15 where pgp_keypair_fpr = ?1 ;"; + sql_mark_as_compromized = "update trust not indexed set comm_type = 15" + " where pgp_keypair_fpr = ?1 ;"; - sql_crashdump = "select timestamp, title, entity, description, comment from log order by timestamp desc limit ?1 ;"; + sql_crashdump = "select timestamp, title, entity, description, comment" + " from log order by timestamp desc limit ?1 ;"; } int_result = sqlite3_prepare_v2(_session->db, sql_log, (int)strlen(sql_log), diff --git a/test/Makefile b/test/Makefile index 0c7618510..d383178f0 100644 --- a/test/Makefile +++ b/test/Makefile @@ -23,6 +23,7 @@ all: $(TARGET) $(UNIT_TESTS) clean: rm -f *.o $(TARGET) *.a *~ $(UNIT_TESTS) pep_Dokument_Titel.pdf + rm -Rf *.dSYM test: pEpEngineTest LD_LIBRARY_PATH=~/lib:../src ./pEpEngineTest diff --git a/test/msg4.asc b/test/msg4.asc new file mode 100644 index 000000000..860cd102c --- /dev/null +++ b/test/msg4.asc @@ -0,0 +1,172 @@ +From: Outlook Test +To: Volker Birk +Subject: pEp +X-pEp-Version: 1.0 +MIME-Version: 1.0 +Content-Type: multipart/encrypted; boundary="74b0dc5119495cff2ae8944a625558ec"; + protocol="application/pgp-encrypted" + +--74b0dc5119495cff2ae8944a625558ec +Content-Type: application/pgp-encrypted + +Version: 1 +--74b0dc5119495cff2ae8944a625558ec +Content-Type: application/octet-stream +Content-Transfer-Encoding: 7bit +Content-Disposition: inline; filename="msg.asc" + +-----BEGIN PGP MESSAGE----- + +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 +=R4JX +-----END PGP MESSAGE----- +YAW8tu5u4a4YWEwHrYsur7dcR0s4Evz/k5R/1NyqRlA0s +7vBZWIEL+lQQWi7PkZaQUt2I83FUdIkBrENHadG7OkV0Z57Ck2FmCH0PVS6H2vKz +Fzl9gL1SwrOdgjUXMiDv6DpiqNQZhbFV0Zszm+jjaJ1LRqaA1MHoL+dMqq8s1N0x +MMQ18SszTHKa2LyrReBshvpjnfUZQTLNp2A033nb97mmrZ+tigVfUguEbb7sUI76 +AnYGDps4RLJh62odiQ3fjIOKrdTdMgoON5RGebgHnRKlU3647NwKEjgO9zpFhAhd +ZRw5IVbEXNfRlFzdsfqrGx5vkZZrNKrd5wXN40GQQ2Kuxf4qviI9Lp0+z7z3nCJI +h6eqGQNn7XyMu +--74b0dc5119495cff2ae8944a625558ec--