diff --git a/core/ssb.js b/core/ssb.js index f6b6b639..c40272d9 100644 --- a/core/ssb.js +++ b/core/ssb.js @@ -219,7 +219,9 @@ function ebtReplicateSendClock(request, have) { } var to_send = {} - for (let id of ids) { + var offset = Math.floor(Math.random() * ids.length); + for (var i = 0; i < ids.length; i++) { + var id = ids[(i + offset) % ids.length]; if (last_sent[id] === undefined || message[id] > last_sent[id]) { last_sent[id] = to_send[id] = message[id] === -1 ? -1 : message[id] << 1; } diff --git a/src/main.c b/src/main.c index a5235d12..f045e0fb 100644 --- a/src/main.c +++ b/src/main.c @@ -569,20 +569,35 @@ static int _tf_command_check(const char* file, int argc, char* argv[]) int extra_count = 0; const char *err = NULL; XOPT_PARSE(file, XOPT_CTX_KEEPFIRST | XOPT_CTX_STRICT, options, &args, argc, (const char**)argv, &extra_count, &extras, &err, stderr, "post [options]", "options:", NULL, 15); - if (extras) - { - free((void*)extras); - } if (err) { + if (extras) + { + free((void*)extras); + } fprintf(stderr, "Error: %s\n", err); return 2; } + bool result = true; sqlite3* db = NULL; sqlite3_open("db.sqlite", &db); - bool result = tf_ssb_db_check(db); + if (extra_count) + { + for (int i = 0; i < extra_count; i++) + { + result = result && tf_ssb_db_check(db, extras[i]); + } + } + else + { + result = tf_ssb_db_check(db, NULL); + } sqlite3_close(db); + if (extras) + { + free((void*)extras); + } return result ? EXIT_SUCCESS : EXIT_FAILURE; xopt_help: diff --git a/src/ssb.c b/src/ssb.c index d5d03565..9f9b48d8 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -512,6 +512,25 @@ static const uint8_t* _utf8_to_cp(const uint8_t* ch, uint32_t* out_cp) return ch + actual_len; } +static uint32_t _cp_to_utf16(uint32_t cp, uint16_t* out_h, uint16_t* out_l) +{ + if (cp < 0x10000) + { + *out_h = 0; + *out_l = cp & 0xffff; + return cp; + } + else + { + uint32_t t = cp - 0x10000; + uint32_t h = ((t << 12) >> 22) + 0xd800; + uint32_t l = ((t << 22) >> 22) + 0xdc00; + *out_h = h & 0xffff; + *out_l = l & 0xffff; + return (h << 16) | (l & 0xffff); + } +} + void tf_ssb_calculate_message_id(JSContext* context, JSValue message, char* out_id, size_t out_id_size) { JSValue idval = JS_JSONStringify(context, message, JS_NULL, JS_NewInt32(context, 2)); @@ -525,7 +544,17 @@ void tf_ssb_calculate_message_id(JSContext* context, JSValue message, char* out_ { uint32_t cp = 0; p = _utf8_to_cp(p, &cp); - *write_pos++ = (cp & 0xff); + uint16_t h = 0; + uint16_t l = 0; + _cp_to_utf16(cp, &h, &l); + if (h) + { + *write_pos++ = h & 0xff; + } + if (l) + { + *write_pos++ = l & 0xff; + } } size_t latin1_len = write_pos - (uint8_t*)latin1; *write_pos++ = '\0'; diff --git a/src/ssb.db.c b/src/ssb.db.c index 2e58919c..d77aa387 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -545,14 +545,21 @@ bool _tf_ssb_update_message_id(sqlite3* db, const char* old_id, const char* new_ return success; } -bool tf_ssb_db_check(sqlite3* db) +bool tf_ssb_db_check(sqlite3* db, const char* check_author) { JSRuntime* runtime = JS_NewRuntime(); JSContext* context = JS_NewContext(runtime); sqlite3_stmt* statement = NULL; - if (sqlite3_prepare(db, "SELECT id, previous, author, sequence, timestamp, hash, content, signature, sequence_before_author FROM messages ORDER BY author, sequence", -1, &statement, NULL) == SQLITE_OK) + int result = check_author ? + sqlite3_prepare(db, "SELECT id, previous, author, sequence, timestamp, hash, content, signature, sequence_before_author FROM messages WHERE author = ? ORDER BY author, sequence", -1, &statement, NULL) : + sqlite3_prepare(db, "SELECT id, previous, author, sequence, timestamp, hash, content, signature, sequence_before_author FROM messages ORDER BY author, sequence", -1, &statement, NULL); + if (result == SQLITE_OK) { + if (check_author) + { + sqlite3_bind_text(statement, 1, check_author, -1, NULL); + } char previous_id[k_id_base64_len]; while (sqlite3_step(statement) == SQLITE_ROW) { diff --git a/src/ssb.db.h b/src/ssb.db.h index 1e6f3145..20f8c6ed 100644 --- a/src/ssb.db.h +++ b/src/ssb.db.h @@ -16,4 +16,4 @@ bool tf_ssb_db_get_latest_message_by_author(tf_ssb_t* ssb, const char* author, i void tf_ssb_db_visit_query(tf_ssb_t* ssb, const char* query, const JSValue binds, void (*callback)(JSValue row, void* user_data), void* user_data); typedef struct sqlite3 sqlite3; -bool tf_ssb_db_check(sqlite3* db); +bool tf_ssb_db_check(sqlite3* db, const char* author);