tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
March 2019
- 20 participants
- 3265 discussions

[tor/release-0.4.0] Merge remote-tracking branch 'tor-github/pr/848' into maint-0.4.0
by teor@torproject.org 26 Mar '19
by teor@torproject.org 26 Mar '19
26 Mar '19
commit 828033001bac114eaf94c3586520f0dce167d06c
Merge: 8bc3ac6a8 669ec6432
Author: teor <teor(a)torproject.org>
Date: Tue Mar 26 16:56:45 2019 +1000
Merge remote-tracking branch 'tor-github/pr/848' into maint-0.4.0
changes/cid1444119 | 3 +++
src/feature/dircommon/consdiff.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --cc src/feature/dircommon/consdiff.c
index 698f54801,000000000..8e93953f7
mode 100644,000000..100644
--- a/src/feature/dircommon/consdiff.c
+++ b/src/feature/dircommon/consdiff.c
@@@ -1,1418 -1,0 +1,1418 @@@
+/* Copyright (c) 2014, Daniel Martí
+ * Copyright (c) 2014-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file consdiff.c
+ * \brief Consensus diff implementation, including both the generation and the
+ * application of diffs in a minimal ed format.
+ *
+ * The consensus diff application is done in consdiff_apply_diff, which relies
+ * on apply_ed_diff for the main ed diff part and on some digest helper
+ * functions to check the digest hashes found in the consensus diff header.
+ *
+ * The consensus diff generation is more complex. consdiff_gen_diff generates
+ * it, relying on gen_ed_diff to generate the ed diff and some digest helper
+ * functions to generate the digest hashes.
+ *
+ * gen_ed_diff is the tricky bit. In it simplest form, it will take quadratic
+ * time and linear space to generate an ed diff given two smartlists. As shown
+ * in its comment section, calling calc_changes on the entire two consensuses
+ * will calculate what is to be added and what is to be deleted in the diff.
+ * Its comment section briefly explains how it works.
+ *
+ * In our case specific to consensuses, we take advantage of the fact that
+ * consensuses list routers sorted by their identities. We use that
+ * information to avoid running calc_changes on the whole smartlists.
+ * gen_ed_diff will navigate through the two consensuses identity by identity
+ * and will send small couples of slices to calc_changes, keeping the running
+ * time near-linear. This is explained in more detail in the gen_ed_diff
+ * comments.
+ *
+ * The allocation strategy tries to save time and memory by avoiding needless
+ * copies. Instead of actually splitting the inputs into separate strings, we
+ * allocate cdline_t objects, each of which represents a line in the original
+ * object or in the output. We use memarea_t allocators to manage the
+ * temporary memory we use when generating or applying diffs.
+ **/
+
+#define CONSDIFF_PRIVATE
+
+#include "core/or/or.h"
+#include "feature/dircommon/consdiff.h"
+#include "lib/memarea/memarea.h"
+#include "feature/dirparse/ns_parse.h"
+
+static const char* ns_diff_version = "network-status-diff-version 1";
+static const char* hash_token = "hash";
+
+static char *consensus_join_lines(const smartlist_t *inp);
+
+/** Return true iff a and b have the same contents. */
+STATIC int
+lines_eq(const cdline_t *a, const cdline_t *b)
+{
+ return a->len == b->len && fast_memeq(a->s, b->s, a->len);
+}
+
+/** Return true iff a has the same contents as the nul-terminated string b. */
+STATIC int
+line_str_eq(const cdline_t *a, const char *b)
+{
+ const size_t len = strlen(b);
+ tor_assert(len <= UINT32_MAX);
+ cdline_t bline = { b, (uint32_t)len };
+ return lines_eq(a, &bline);
+}
+
+/** Return true iff a begins with the same contents as the nul-terminated
+ * string b. */
+static int
+line_starts_with_str(const cdline_t *a, const char *b)
+{
+ const size_t len = strlen(b);
+ tor_assert(len <= UINT32_MAX);
+ return a->len >= len && fast_memeq(a->s, b, len);
+}
+
+/** Return a new cdline_t holding as its contents the nul-terminated
+ * string s. Use the provided memory area for storage. */
+static cdline_t *
+cdline_linecpy(memarea_t *area, const char *s)
+{
+ size_t len = strlen(s);
+ const char *ss = memarea_memdup(area, s, len);
+ cdline_t *line = memarea_alloc(area, sizeof(cdline_t));
+ line->s = ss;
+ line->len = (uint32_t)len;
+ return line;
+}
+
+/** Add a cdline_t to <b>lst</b> holding as its contents the nul-terminated
+ * string s. Use the provided memory area for storage. */
+STATIC void
+smartlist_add_linecpy(smartlist_t *lst, memarea_t *area, const char *s)
+{
+ smartlist_add(lst, cdline_linecpy(area, s));
+}
+
+/** Compute the digest of <b>cons</b>, and store the result in
+ * <b>digest_out</b>. Return 0 on success, -1 on failure. */
+/* This is a separate, mockable function so that we can override it when
+ * fuzzing. */
+MOCK_IMPL(STATIC int,
+consensus_compute_digest,(const char *cons, size_t len,
+ consensus_digest_t *digest_out))
+{
+ int r = crypto_digest256((char*)digest_out->sha3_256,
+ cons, len, DIGEST_SHA3_256);
+ return r;
+}
+
+/** Compute the digest-as-signed of <b>cons</b>, and store the result in
+ * <b>digest_out</b>. Return 0 on success, -1 on failure. */
+/* This is a separate, mockable function so that we can override it when
+ * fuzzing. */
+MOCK_IMPL(STATIC int,
+consensus_compute_digest_as_signed,(const char *cons, size_t len,
+ consensus_digest_t *digest_out))
+{
+ return router_get_networkstatus_v3_sha3_as_signed(digest_out->sha3_256,
+ cons, len);
+}
+
+/** Return true iff <b>d1</b> and <b>d2</b> contain the same digest */
+/* This is a separate, mockable function so that we can override it when
+ * fuzzing. */
+MOCK_IMPL(STATIC int,
+consensus_digest_eq,(const uint8_t *d1,
+ const uint8_t *d2))
+{
+ return fast_memeq(d1, d2, DIGEST256_LEN);
+}
+
+/** Create (allocate) a new slice from a smartlist. Assumes that the start
+ * and the end indexes are within the bounds of the initial smartlist. The end
+ * element is not part of the resulting slice. If end is -1, the slice is to
+ * reach the end of the smartlist.
+ */
+STATIC smartlist_slice_t *
+smartlist_slice(const smartlist_t *list, int start, int end)
+{
+ int list_len = smartlist_len(list);
+ tor_assert(start >= 0);
+ tor_assert(start <= list_len);
+ if (end == -1) {
+ end = list_len;
+ }
+ tor_assert(start <= end);
+
+ smartlist_slice_t *slice = tor_malloc(sizeof(smartlist_slice_t));
+ slice->list = list;
+ slice->offset = start;
+ slice->len = end - start;
+ return slice;
+}
+
+/** Helper: Compute the longest common subsequence lengths for the two slices.
+ * Used as part of the diff generation to find the column at which to split
+ * slice2 while still having the optimal solution.
+ * If direction is -1, the navigation is reversed. Otherwise it must be 1.
+ * The length of the resulting integer array is that of the second slice plus
+ * one.
+ */
+STATIC int *
+lcs_lengths(const smartlist_slice_t *slice1, const smartlist_slice_t *slice2,
+ int direction)
+{
+ size_t a_size = sizeof(int) * (slice2->len+1);
+
+ /* Resulting lcs lengths. */
+ int *result = tor_malloc_zero(a_size);
+ /* Copy of the lcs lengths from the last iteration. */
+ int *prev = tor_malloc(a_size);
+
+ tor_assert(direction == 1 || direction == -1);
+
+ int si = slice1->offset;
+ if (direction == -1) {
+ si += (slice1->len-1);
+ }
+
+ for (int i = 0; i < slice1->len; ++i, si+=direction) {
+
+ const cdline_t *line1 = smartlist_get(slice1->list, si);
+ /* Store the last results. */
+ memcpy(prev, result, a_size);
+
+ int sj = slice2->offset;
+ if (direction == -1) {
+ sj += (slice2->len-1);
+ }
+
+ for (int j = 0; j < slice2->len; ++j, sj+=direction) {
+
+ const cdline_t *line2 = smartlist_get(slice2->list, sj);
+ if (lines_eq(line1, line2)) {
+ /* If the lines are equal, the lcs is one line longer. */
+ result[j + 1] = prev[j] + 1;
+ } else {
+ /* If not, see what lcs parent path is longer. */
+ result[j + 1] = MAX(result[j], prev[j + 1]);
+ }
+ }
+ }
+ tor_free(prev);
+ return result;
+}
+
+/** Helper: Trim any number of lines that are equally at the start or the end
+ * of both slices.
+ */
+STATIC void
+trim_slices(smartlist_slice_t *slice1, smartlist_slice_t *slice2)
+{
+ while (slice1->len>0 && slice2->len>0) {
+ const cdline_t *line1 = smartlist_get(slice1->list, slice1->offset);
+ const cdline_t *line2 = smartlist_get(slice2->list, slice2->offset);
+ if (!lines_eq(line1, line2)) {
+ break;
+ }
+ slice1->offset++; slice1->len--;
+ slice2->offset++; slice2->len--;
+ }
+
+ int i1 = (slice1->offset+slice1->len)-1;
+ int i2 = (slice2->offset+slice2->len)-1;
+
+ while (slice1->len>0 && slice2->len>0) {
+ const cdline_t *line1 = smartlist_get(slice1->list, i1);
+ const cdline_t *line2 = smartlist_get(slice2->list, i2);
+ if (!lines_eq(line1, line2)) {
+ break;
+ }
+ i1--;
+ slice1->len--;
+ i2--;
+ slice2->len--;
+ }
+}
+
+/** Like smartlist_string_pos, but uses a cdline_t, and is restricted to the
+ * bounds of the slice.
+ */
+STATIC int
+smartlist_slice_string_pos(const smartlist_slice_t *slice,
+ const cdline_t *string)
+{
+ int end = slice->offset + slice->len;
+ for (int i = slice->offset; i < end; ++i) {
+ const cdline_t *el = smartlist_get(slice->list, i);
+ if (lines_eq(el, string)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+/** Helper: Set all the appropriate changed booleans to true. The first slice
+ * must be of length 0 or 1. All the lines of slice1 and slice2 which are not
+ * present in the other slice will be set to changed in their bool array.
+ * The two changed bool arrays are passed in the same order as the slices.
+ */
+STATIC void
+set_changed(bitarray_t *changed1, bitarray_t *changed2,
+ const smartlist_slice_t *slice1, const smartlist_slice_t *slice2)
+{
+ int toskip = -1;
+ tor_assert(slice1->len == 0 || slice1->len == 1);
+
+ if (slice1->len == 1) {
+ const cdline_t *line_common = smartlist_get(slice1->list, slice1->offset);
+ toskip = smartlist_slice_string_pos(slice2, line_common);
+ if (toskip == -1) {
+ bitarray_set(changed1, slice1->offset);
+ }
+ }
+ int end = slice2->offset + slice2->len;
+ for (int i = slice2->offset; i < end; ++i) {
+ if (i != toskip) {
+ bitarray_set(changed2, i);
+ }
+ }
+}
+
+/*
+ * Helper: Given that slice1 has been split by half into top and bot, we want
+ * to fetch the column at which to split slice2 so that we are still on track
+ * to the optimal diff solution, i.e. the shortest one. We use lcs_lengths
+ * since the shortest diff is just another way to say the longest common
+ * subsequence.
+ */
+static int
+optimal_column_to_split(const smartlist_slice_t *top,
+ const smartlist_slice_t *bot,
+ const smartlist_slice_t *slice2)
+{
+ int *lens_top = lcs_lengths(top, slice2, 1);
+ int *lens_bot = lcs_lengths(bot, slice2, -1);
+ int column=0, max_sum=-1;
+
+ for (int i = 0; i < slice2->len+1; ++i) {
+ int sum = lens_top[i] + lens_bot[slice2->len-i];
+ if (sum > max_sum) {
+ column = i;
+ max_sum = sum;
+ }
+ }
+ tor_free(lens_top);
+ tor_free(lens_bot);
+
+ return column;
+}
+
+/**
+ * Helper: Figure out what elements are new or gone on the second smartlist
+ * relative to the first smartlist, and store the booleans in the bitarrays.
+ * True on the first bitarray means the element is gone, true on the second
+ * bitarray means it's new.
+ *
+ * In its base case, either of the smartlists is of length <= 1 and we can
+ * quickly see what elements are new or are gone. In the other case, we will
+ * split one smartlist by half and we'll use optimal_column_to_split to find
+ * the optimal column at which to split the second smartlist so that we are
+ * finding the smallest diff possible.
+ */
+STATIC void
+calc_changes(smartlist_slice_t *slice1,
+ smartlist_slice_t *slice2,
+ bitarray_t *changed1, bitarray_t *changed2)
+{
+ trim_slices(slice1, slice2);
+
+ if (slice1->len <= 1) {
+ set_changed(changed1, changed2, slice1, slice2);
+
+ } else if (slice2->len <= 1) {
+ set_changed(changed2, changed1, slice2, slice1);
+
+ /* Keep on splitting the slices in two. */
+ } else {
+ smartlist_slice_t *top, *bot, *left, *right;
+
+ /* Split the first slice in half. */
+ int mid = slice1->len/2;
+ top = smartlist_slice(slice1->list, slice1->offset, slice1->offset+mid);
+ bot = smartlist_slice(slice1->list, slice1->offset+mid,
+ slice1->offset+slice1->len);
+
+ /* Split the second slice by the optimal column. */
+ int mid2 = optimal_column_to_split(top, bot, slice2);
+ left = smartlist_slice(slice2->list, slice2->offset, slice2->offset+mid2);
+ right = smartlist_slice(slice2->list, slice2->offset+mid2,
+ slice2->offset+slice2->len);
+
+ calc_changes(top, left, changed1, changed2);
+ calc_changes(bot, right, changed1, changed2);
+ tor_free(top);
+ tor_free(bot);
+ tor_free(left);
+ tor_free(right);
+ }
+}
+
+/* This table is from crypto.c. The SP and PAD defines are different. */
+#define NOT_VALID_BASE64 255
+#define X NOT_VALID_BASE64
+#define SP NOT_VALID_BASE64
+#define PAD NOT_VALID_BASE64
+static const uint8_t base64_compare_table[256] = {
+ X, X, X, X, X, X, X, X, X, SP, SP, SP, X, SP, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ SP, X, X, X, X, X, X, X, X, X, X, 62, X, X, X, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, X, X, X, PAD, X, X,
+ X, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, X, X, X, X, X,
+ X, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+ X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X,
+};
+
+/** Helper: Get the identity hash from a router line, assuming that the line
+ * at least appears to be a router line and thus starts with "r ".
+ *
+ * If an identity hash is found, store it (without decoding it) in
+ * <b>hash_out</b>, and return 0. On failure, return -1.
+ */
+STATIC int
+get_id_hash(const cdline_t *line, cdline_t *hash_out)
+{
+ if (line->len < 2)
+ return -1;
+
+ /* Skip the router name. */
+ const char *hash = memchr(line->s + 2, ' ', line->len - 2);
+ if (!hash) {
+ return -1;
+ }
+
+ hash++;
+ const char *hash_end = hash;
+ /* Stop when the first non-base64 character is found. Use unsigned chars to
+ * avoid negative indexes causing crashes.
+ */
+ while (base64_compare_table[*((unsigned char*)hash_end)]
+ != NOT_VALID_BASE64 &&
+ hash_end < line->s + line->len) {
+ hash_end++;
+ }
+
+ /* Empty hash. */
+ if (hash_end == hash) {
+ return -1;
+ }
+
+ hash_out->s = hash;
+ /* Always true because lines are limited to this length */
+ tor_assert(hash_end >= hash);
+ tor_assert((size_t)(hash_end - hash) <= UINT32_MAX);
+ hash_out->len = (uint32_t)(hash_end - hash);
+
+ return 0;
+}
+
+/** Helper: Check that a line is a valid router entry. We must at least be
+ * able to fetch a proper identity hash from it for it to be valid.
+ */
+STATIC int
+is_valid_router_entry(const cdline_t *line)
+{
+ if (line->len < 2 || fast_memneq(line->s, "r ", 2))
+ return 0;
+ cdline_t tmp;
+ return (get_id_hash(line, &tmp) == 0);
+}
+
+/** Helper: Find the next router line starting at the current position.
+ * Assumes that cur is lower than the length of the smartlist, i.e. it is a
+ * line within the bounds of the consensus. The only exception is when we
+ * don't want to skip the first line, in which case cur will be -1.
+ */
+STATIC int
+next_router(const smartlist_t *cons, int cur)
+{
+ int len = smartlist_len(cons);
+ tor_assert(cur >= -1 && cur < len);
+
+ if (++cur >= len) {
+ return len;
+ }
+
+ const cdline_t *line = smartlist_get(cons, cur);
+ while (!is_valid_router_entry(line)) {
+ if (++cur >= len) {
+ return len;
+ }
+ line = smartlist_get(cons, cur);
+ }
+ return cur;
+}
+
+/** Helper: compare two base64-encoded identity hashes, which may be of
+ * different lengths. Comparison ends when the first non-base64 char is found.
+ */
+STATIC int
+base64cmp(const cdline_t *hash1, const cdline_t *hash2)
+{
+ /* NULL is always lower, useful for last_hash which starts at NULL. */
+ if (!hash1->s && !hash2->s) {
+ return 0;
+ }
+ if (!hash1->s) {
+ return -1;
+ }
+ if (!hash2->s) {
+ return 1;
+ }
+
+ /* Don't index with a char; char may be signed. */
+ const unsigned char *a = (unsigned char*)hash1->s;
+ const unsigned char *b = (unsigned char*)hash2->s;
+ const unsigned char *a_end = a + hash1->len;
+ const unsigned char *b_end = b + hash2->len;
+ while (1) {
+ uint8_t av = base64_compare_table[*a];
+ uint8_t bv = base64_compare_table[*b];
+ if (av == NOT_VALID_BASE64) {
+ if (bv == NOT_VALID_BASE64) {
+ /* Both ended with exactly the same characters. */
+ return 0;
+ } else {
+ /* hash2 goes on longer than hash1 and thus hash1 is lower. */
+ return -1;
+ }
+ } else if (bv == NOT_VALID_BASE64) {
+ /* hash1 goes on longer than hash2 and thus hash1 is greater. */
+ return 1;
+ } else if (av < bv) {
+ /* The first difference shows that hash1 is lower. */
+ return -1;
+ } else if (av > bv) {
+ /* The first difference shows that hash1 is greater. */
+ return 1;
+ } else {
+ a++;
+ b++;
+ if (a == a_end) {
+ if (b == b_end) {
+ return 0;
+ } else {
+ return -1;
+ }
+ } else if (b == b_end) {
+ return 1;
+ }
+ }
+ }
+}
+
+/** Structure used to remember the previous and current identity hash of
+ * the "r " lines in a consensus, to enforce well-ordering. */
+typedef struct router_id_iterator_t {
+ cdline_t last_hash;
+ cdline_t hash;
+} router_id_iterator_t;
+
+/**
+ * Initializer for a router_id_iterator_t.
+ */
+#define ROUTER_ID_ITERATOR_INIT { { NULL, 0 }, { NULL, 0 } }
+
+/** Given an index *<b>idxp</b> into the consensus at <b>cons</b>, advance
+ * the index to the next router line ("r ...") in the consensus, or to
+ * an index one after the end of the list if there is no such line.
+ *
+ * Use <b>iter</b> to record the hash of the found router line, if any,
+ * and to enforce ordering on the hashes. If the hashes are mis-ordered,
+ * return -1. Else, return 0.
+ **/
+static int
+find_next_router_line(const smartlist_t *cons,
+ const char *consname,
+ int *idxp,
+ router_id_iterator_t *iter)
+{
+ *idxp = next_router(cons, *idxp);
+ if (*idxp < smartlist_len(cons)) {
+ memcpy(&iter->last_hash, &iter->hash, sizeof(cdline_t));
+ if (get_id_hash(smartlist_get(cons, *idxp), &iter->hash) < 0 ||
+ base64cmp(&iter->hash, &iter->last_hash) <= 0) {
+ log_warn(LD_CONSDIFF, "Refusing to generate consensus diff because "
+ "the %s consensus doesn't have its router entries sorted "
+ "properly.", consname);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/** Line-prefix indicating the beginning of the signatures section that we
+ * intend to delete. */
+#define START_OF_SIGNATURES_SECTION "directory-signature "
+
+/** Pre-process a consensus in <b>cons</b> (represented as a list of cdline_t)
+ * to remove the signatures from it. If the footer is removed, return a
+ * cdline_t containing a delete command to delete the footer, allocated in
+ * <b>area</>. If no footer is removed, return NULL.
+ *
+ * We remove the signatures here because they are not themselves signed, and
+ * as such there might be different encodings for them.
+ */
+static cdline_t *
+preprocess_consensus(memarea_t *area,
+ smartlist_t *cons)
+{
+ int idx;
+ int dirsig_idx = -1;
+ for (idx = 0; idx < smartlist_len(cons); ++idx) {
+ cdline_t *line = smartlist_get(cons, idx);
+ if (line_starts_with_str(line, START_OF_SIGNATURES_SECTION)) {
+ dirsig_idx = idx;
+ break;
+ }
+ }
+ if (dirsig_idx >= 0) {
+ char buf[64];
+ while (smartlist_len(cons) > dirsig_idx)
+ smartlist_del(cons, dirsig_idx);
+ tor_snprintf(buf, sizeof(buf), "%d,$d", dirsig_idx+1);
+ return cdline_linecpy(area, buf);
+ } else {
+ return NULL;
+ }
+}
+
+/** Generate an ed diff as a smartlist from two consensuses, also given as
+ * smartlists. Will return NULL if the diff could not be generated, which can
+ * happen if any lines the script had to add matched "." or if the routers
+ * were not properly ordered.
+ *
+ * All cdline_t objects in the resulting object are either references to lines
+ * in one of the inputs, or are newly allocated lines in the provided memarea.
+ *
+ * This implementation is consensus-specific. To generate an ed diff for any
+ * given input in quadratic time, you can replace all the code until the
+ * navigation in reverse order with the following:
+ *
+ * int len1 = smartlist_len(cons1);
+ * int len2 = smartlist_len(cons2);
+ * bitarray_t *changed1 = bitarray_init_zero(len1);
+ * bitarray_t *changed2 = bitarray_init_zero(len2);
+ * cons1_sl = smartlist_slice(cons1, 0, -1);
+ * cons2_sl = smartlist_slice(cons2, 0, -1);
+ * calc_changes(cons1_sl, cons2_sl, changed1, changed2);
+ */
+STATIC smartlist_t *
+gen_ed_diff(const smartlist_t *cons1_orig, const smartlist_t *cons2,
+ memarea_t *area)
+{
+ smartlist_t *cons1 = smartlist_new();
+ smartlist_add_all(cons1, cons1_orig);
+ cdline_t *remove_trailer = preprocess_consensus(area, cons1);
+
+ int len1 = smartlist_len(cons1);
+ int len2 = smartlist_len(cons2);
+ smartlist_t *result = smartlist_new();
+
+ if (remove_trailer) {
+ /* There's a delete-the-trailer line at the end, so add it here. */
+ smartlist_add(result, remove_trailer);
+ }
+
+ /* Initialize the changed bitarrays to zero, so that calc_changes only needs
+ * to set the ones that matter and leave the rest untouched.
+ */
+ bitarray_t *changed1 = bitarray_init_zero(len1);
+ bitarray_t *changed2 = bitarray_init_zero(len2);
+ int i1=-1, i2=-1;
+ int start1=0, start2=0;
+
+ /* To check that hashes are ordered properly */
+ router_id_iterator_t iter1 = ROUTER_ID_ITERATOR_INIT;
+ router_id_iterator_t iter2 = ROUTER_ID_ITERATOR_INIT;
+
+ /* i1 and i2 are initialized at the first line of each consensus. They never
+ * reach past len1 and len2 respectively, since next_router doesn't let that
+ * happen. i1 and i2 are advanced by at least one line at each iteration as
+ * long as they have not yet reached len1 and len2, so the loop is
+ * guaranteed to end, and each pair of (i1,i2) will be inspected at most
+ * once.
+ */
+ while (i1 < len1 || i2 < len2) {
+
+ /* Advance each of the two navigation positions by one router entry if not
+ * yet at the end.
+ */
+ if (i1 < len1) {
+ if (find_next_router_line(cons1, "base", &i1, &iter1) < 0) {
+ goto error_cleanup;
+ }
+ }
+
+ if (i2 < len2) {
+ if (find_next_router_line(cons2, "target", &i2, &iter2) < 0) {
+ goto error_cleanup;
+ }
+ }
+
+ /* If we have reached the end of both consensuses, there is no need to
+ * compare hashes anymore, since this is the last iteration.
+ */
+ if (i1 < len1 || i2 < len2) {
+
+ /* Keep on advancing the lower (by identity hash sorting) position until
+ * we have two matching positions. The only other possible outcome is
+ * that a lower position reaches the end of the consensus before it can
+ * reach a hash that is no longer the lower one. Since there will always
+ * be a lower hash for as long as the loop runs, one of the two indexes
+ * will always be incremented, thus assuring that the loop must end
+ * after a finite number of iterations. If that cannot be because said
+ * consensus has already reached the end, both are extended to their
+ * respecting ends since we are done.
+ */
+ int cmp = base64cmp(&iter1.hash, &iter2.hash);
+ while (cmp != 0) {
+ if (i1 < len1 && cmp < 0) {
+ if (find_next_router_line(cons1, "base", &i1, &iter1) < 0) {
+ goto error_cleanup;
+ }
+ if (i1 == len1) {
+ /* We finished the first consensus, so grab all the remaining
+ * lines of the second consensus and finish up.
+ */
+ i2 = len2;
+ break;
+ }
+ } else if (i2 < len2 && cmp > 0) {
+ if (find_next_router_line(cons2, "target", &i2, &iter2) < 0) {
+ goto error_cleanup;
+ }
+ if (i2 == len2) {
+ /* We finished the second consensus, so grab all the remaining
+ * lines of the first consensus and finish up.
+ */
+ i1 = len1;
+ break;
+ }
+ } else {
+ i1 = len1;
+ i2 = len2;
+ break;
+ }
+ cmp = base64cmp(&iter1.hash, &iter2.hash);
+ }
+ }
+
+ /* Make slices out of these chunks (up to the common router entry) and
+ * calculate the changes for them.
+ * Error if any of the two slices are longer than 10K lines. That should
+ * never happen with any pair of real consensuses. Feeding more than 10K
+ * lines to calc_changes would be very slow anyway.
+ */
+#define MAX_LINE_COUNT (10000)
+ if (i1-start1 > MAX_LINE_COUNT || i2-start2 > MAX_LINE_COUNT) {
+ log_warn(LD_CONSDIFF, "Refusing to generate consensus diff because "
+ "we found too few common router ids.");
+ goto error_cleanup;
+ }
+
+ smartlist_slice_t *cons1_sl = smartlist_slice(cons1, start1, i1);
+ smartlist_slice_t *cons2_sl = smartlist_slice(cons2, start2, i2);
+ calc_changes(cons1_sl, cons2_sl, changed1, changed2);
+ tor_free(cons1_sl);
+ tor_free(cons2_sl);
+ start1 = i1, start2 = i2;
+ }
+
+ /* Navigate the changes in reverse order and generate one ed command for
+ * each chunk of changes.
+ */
+ i1=len1-1, i2=len2-1;
+ char buf[128];
+ while (i1 >= 0 || i2 >= 0) {
+
+ int start1x, start2x, end1, end2, added, deleted;
+
+ /* We are at a point were no changed bools are true, so just keep going. */
+ if (!(i1 >= 0 && bitarray_is_set(changed1, i1)) &&
+ !(i2 >= 0 && bitarray_is_set(changed2, i2))) {
+ if (i1 >= 0) {
+ i1--;
+ }
+ if (i2 >= 0) {
+ i2--;
+ }
+ continue;
+ }
+
+ end1 = i1, end2 = i2;
+
+ /* Grab all contiguous changed lines */
+ while (i1 >= 0 && bitarray_is_set(changed1, i1)) {
+ i1--;
+ }
+ while (i2 >= 0 && bitarray_is_set(changed2, i2)) {
+ i2--;
+ }
+
+ start1x = i1+1, start2x = i2+1;
+ added = end2-i2, deleted = end1-i1;
+
+ if (added == 0) {
+ if (deleted == 1) {
+ tor_snprintf(buf, sizeof(buf), "%id", start1x+1);
+ smartlist_add_linecpy(result, area, buf);
+ } else {
+ tor_snprintf(buf, sizeof(buf), "%i,%id", start1x+1, start1x+deleted);
+ smartlist_add_linecpy(result, area, buf);
+ }
+ } else {
+ int i;
+ if (deleted == 0) {
+ tor_snprintf(buf, sizeof(buf), "%ia", start1x);
+ smartlist_add_linecpy(result, area, buf);
+ } else if (deleted == 1) {
+ tor_snprintf(buf, sizeof(buf), "%ic", start1x+1);
+ smartlist_add_linecpy(result, area, buf);
+ } else {
+ tor_snprintf(buf, sizeof(buf), "%i,%ic", start1x+1, start1x+deleted);
+ smartlist_add_linecpy(result, area, buf);
+ }
+
+ for (i = start2x; i <= end2; ++i) {
+ cdline_t *line = smartlist_get(cons2, i);
+ if (line_str_eq(line, ".")) {
+ log_warn(LD_CONSDIFF, "Cannot generate consensus diff because "
+ "one of the lines to be added is \".\".");
+ goto error_cleanup;
+ }
+ smartlist_add(result, line);
+ }
+ smartlist_add_linecpy(result, area, ".");
+ }
+ }
+
+ smartlist_free(cons1);
+ bitarray_free(changed1);
+ bitarray_free(changed2);
+
+ return result;
+
+ error_cleanup:
+
+ smartlist_free(cons1);
+ bitarray_free(changed1);
+ bitarray_free(changed2);
+
+ smartlist_free(result);
+
+ return NULL;
+}
+
+/* Helper: Read a base-10 number between 0 and INT32_MAX from <b>s</b> and
+ * store it in <b>num_out</b>. Advance <b>s</b> to the characer immediately
+ * after the number. Return 0 on success, -1 on failure. */
+static int
+get_linenum(const char **s, int *num_out)
+{
+ int ok;
+ char *next;
+ if (!TOR_ISDIGIT(**s)) {
+ return -1;
+ }
+ *num_out = (int) tor_parse_long(*s, 10, 0, INT32_MAX, &ok, &next);
+ if (ok && next) {
+ *s = next;
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+/** Apply the ed diff, starting at <b>diff_starting_line</b>, to the consensus
+ * and return a new consensus, also as a line-based smartlist. Will return
+ * NULL if the ed diff is not properly formatted.
+ *
+ * All cdline_t objects in the resulting object are references to lines
+ * in one of the inputs; nothing is copied.
+ */
+STATIC smartlist_t *
+apply_ed_diff(const smartlist_t *cons1, const smartlist_t *diff,
+ int diff_starting_line)
+{
+ int diff_len = smartlist_len(diff);
+ int j = smartlist_len(cons1);
+ smartlist_t *cons2 = smartlist_new();
+
+ for (int i=diff_starting_line; i<diff_len; ++i) {
+ const cdline_t *diff_cdline = smartlist_get(diff, i);
+ char diff_line[128];
+
+ if (diff_cdline->len > sizeof(diff_line) - 1) {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "an ed command was far too long");
+ goto error_cleanup;
+ }
+ /* Copy the line to make it nul-terminated. */
+ memcpy(diff_line, diff_cdline->s, diff_cdline->len);
+ diff_line[diff_cdline->len] = 0;
+ const char *ptr = diff_line;
+ int start = 0, end = 0;
+ int had_range = 0;
+ int end_was_eof = 0;
+ if (get_linenum(&ptr, &start) < 0) {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "an ed command was missing a line number.");
+ goto error_cleanup;
+ }
+ if (*ptr == ',') {
+ /* Two-item range */
+ had_range = 1;
+ ++ptr;
+ if (*ptr == '$') {
+ end_was_eof = 1;
+ end = smartlist_len(cons1);
+ ++ptr;
+ } else if (get_linenum(&ptr, &end) < 0) {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "an ed command was missing a range end line number.");
+ goto error_cleanup;
+ }
+ /* Incoherent range. */
+ if (end <= start) {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "an invalid range was found in an ed command.");
+ goto error_cleanup;
+ }
+ } else {
+ /* We'll take <n1> as <n1>,<n1> for simplicity. */
+ end = start;
+ }
+
+ if (end > j) {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "its commands are not properly sorted in reverse order.");
+ goto error_cleanup;
+ }
+
+ if (*ptr == '\0') {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "a line with no ed command was found");
+ goto error_cleanup;
+ }
+
+ if (*(ptr+1) != '\0') {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "an ed command longer than one char was found.");
+ goto error_cleanup;
+ }
+
+ char action = *ptr;
+
+ switch (action) {
+ case 'a':
+ case 'c':
+ case 'd':
+ break;
+ default:
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "an unrecognised ed command was found.");
+ goto error_cleanup;
+ }
+
+ /** $ is not allowed with non-d actions. */
+ if (end_was_eof && action != 'd') {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "it wanted to use $ with a command other than delete");
+ goto error_cleanup;
+ }
+
+ /* 'a' commands are not allowed to have ranges. */
+ if (had_range && action == 'a') {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "it wanted to add lines after a range.");
+ goto error_cleanup;
+ }
+
+ /* Add unchanged lines. */
+ for (; j && j > end; --j) {
+ cdline_t *cons_line = smartlist_get(cons1, j-1);
+ smartlist_add(cons2, cons_line);
+ }
+
+ /* Ignore removed lines. */
+ if (action == 'c' || action == 'd') {
+ while (--j >= start) {
+ /* Skip line */
+ }
+ }
+
+ /* Add new lines in reverse order, since it will all be reversed at the
+ * end.
+ */
+ if (action == 'a' || action == 'c') {
+ int added_end = i;
+
+ i++; /* Skip the line with the range and command. */
+ while (i < diff_len) {
+ if (line_str_eq(smartlist_get(diff, i), ".")) {
+ break;
+ }
+ if (++i == diff_len) {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "it has lines to be inserted that don't end with a \".\".");
+ goto error_cleanup;
+ }
+ }
+
+ int added_i = i-1;
+
+ /* It would make no sense to add zero new lines. */
+ if (added_i == added_end) {
+ log_warn(LD_CONSDIFF, "Could not apply consensus diff because "
+ "it has an ed command that tries to insert zero lines.");
+ goto error_cleanup;
+ }
+
+ while (added_i > added_end) {
+ cdline_t *added_line = smartlist_get(diff, added_i--);
+ smartlist_add(cons2, added_line);
+ }
+ }
+ }
+
+ /* Add remaining unchanged lines. */
+ for (; j > 0; --j) {
+ cdline_t *cons_line = smartlist_get(cons1, j-1);
+ smartlist_add(cons2, cons_line);
+ }
+
+ /* Reverse the whole thing since we did it from the end. */
+ smartlist_reverse(cons2);
+ return cons2;
+
+ error_cleanup:
+
+ smartlist_free(cons2);
+
+ return NULL;
+}
+
+/** Generate a consensus diff as a smartlist from two given consensuses, also
+ * as smartlists. Will return NULL if the consensus diff could not be
+ * generated. Neither of the two consensuses are modified in any way, so it's
+ * up to the caller to free their resources.
+ */
+smartlist_t *
+consdiff_gen_diff(const smartlist_t *cons1,
+ const smartlist_t *cons2,
+ const consensus_digest_t *digests1,
+ const consensus_digest_t *digests2,
+ memarea_t *area)
+{
+ smartlist_t *ed_diff = gen_ed_diff(cons1, cons2, area);
+ /* ed diff could not be generated - reason already logged by gen_ed_diff. */
+ if (!ed_diff) {
+ goto error_cleanup;
+ }
+
+ /* See that the script actually produces what we want. */
+ smartlist_t *ed_cons2 = apply_ed_diff(cons1, ed_diff, 0);
+ if (!ed_cons2) {
+ /* LCOV_EXCL_START -- impossible if diff generation is correct */
+ log_warn(LD_BUG|LD_CONSDIFF, "Refusing to generate consensus diff because "
+ "the generated ed diff could not be tested to successfully generate "
+ "the target consensus.");
+ goto error_cleanup;
+ /* LCOV_EXCL_STOP */
+ }
+
+ int cons2_eq = 1;
+ if (smartlist_len(cons2) == smartlist_len(ed_cons2)) {
+ SMARTLIST_FOREACH_BEGIN(cons2, const cdline_t *, line1) {
+ const cdline_t *line2 = smartlist_get(ed_cons2, line1_sl_idx);
+ if (! lines_eq(line1, line2) ) {
+ cons2_eq = 0;
+ break;
+ }
+ } SMARTLIST_FOREACH_END(line1);
+ } else {
+ cons2_eq = 0;
+ }
+ smartlist_free(ed_cons2);
+ if (!cons2_eq) {
+ /* LCOV_EXCL_START -- impossible if diff generation is correct. */
+ log_warn(LD_BUG|LD_CONSDIFF, "Refusing to generate consensus diff because "
+ "the generated ed diff did not generate the target consensus "
+ "successfully when tested.");
+ goto error_cleanup;
+ /* LCOV_EXCL_STOP */
+ }
+
+ char cons1_hash_hex[HEX_DIGEST256_LEN+1];
+ char cons2_hash_hex[HEX_DIGEST256_LEN+1];
+ base16_encode(cons1_hash_hex, HEX_DIGEST256_LEN+1,
+ (const char*)digests1->sha3_256, DIGEST256_LEN);
+ base16_encode(cons2_hash_hex, HEX_DIGEST256_LEN+1,
+ (const char*)digests2->sha3_256, DIGEST256_LEN);
+
+ /* Create the resulting consensus diff. */
+ char buf[160];
+ smartlist_t *result = smartlist_new();
+ tor_snprintf(buf, sizeof(buf), "%s", ns_diff_version);
+ smartlist_add_linecpy(result, area, buf);
+ tor_snprintf(buf, sizeof(buf), "%s %s %s", hash_token,
+ cons1_hash_hex, cons2_hash_hex);
+ smartlist_add_linecpy(result, area, buf);
+ smartlist_add_all(result, ed_diff);
+ smartlist_free(ed_diff);
+ return result;
+
+ error_cleanup:
+
+ if (ed_diff) {
+ /* LCOV_EXCL_START -- ed_diff is NULL except in unreachable cases above */
+ smartlist_free(ed_diff);
+ /* LCOV_EXCL_STOP */
+ }
+
+ return NULL;
+}
+
+/** Fetch the digest of the base consensus in the consensus diff, encoded in
+ * base16 as found in the diff itself. digest1_out and digest2_out must be of
+ * length DIGEST256_LEN or larger if not NULL.
+ */
+int
+consdiff_get_digests(const smartlist_t *diff,
+ char *digest1_out,
+ char *digest2_out)
+{
+ smartlist_t *hash_words = NULL;
+ const cdline_t *format;
+ char cons1_hash[DIGEST256_LEN], cons2_hash[DIGEST256_LEN];
+ char *cons1_hash_hex, *cons2_hash_hex;
+ if (smartlist_len(diff) < 2) {
+ log_info(LD_CONSDIFF, "The provided consensus diff is too short.");
+ goto error_cleanup;
+ }
+
+ /* Check that it's the format and version we know. */
+ format = smartlist_get(diff, 0);
+ if (!line_str_eq(format, ns_diff_version)) {
+ log_warn(LD_CONSDIFF, "The provided consensus diff format is not known.");
+ goto error_cleanup;
+ }
+
+ /* Grab the base16 digests. */
+ hash_words = smartlist_new();
+ {
+ const cdline_t *line2 = smartlist_get(diff, 1);
+ char *h = tor_memdup_nulterm(line2->s, line2->len);
+ smartlist_split_string(hash_words, h, " ", 0, 0);
+ tor_free(h);
+ }
+
+ /* There have to be three words, the first of which must be hash_token. */
+ if (smartlist_len(hash_words) != 3 ||
+ strcmp(smartlist_get(hash_words, 0), hash_token)) {
+ log_info(LD_CONSDIFF, "The provided consensus diff does not include "
+ "the necessary digests.");
+ goto error_cleanup;
+ }
+
+ /* Expected hashes as found in the consensus diff header. They must be of
+ * length HEX_DIGEST256_LEN, normally 64 hexadecimal characters.
+ * If any of the decodings fail, error to make sure that the hashes are
+ * proper base16-encoded digests.
+ */
+ cons1_hash_hex = smartlist_get(hash_words, 1);
+ cons2_hash_hex = smartlist_get(hash_words, 2);
+ if (strlen(cons1_hash_hex) != HEX_DIGEST256_LEN ||
+ strlen(cons2_hash_hex) != HEX_DIGEST256_LEN) {
+ log_info(LD_CONSDIFF, "The provided consensus diff includes "
+ "base16-encoded digests of incorrect size.");
+ goto error_cleanup;
+ }
+
+ if (base16_decode(cons1_hash, DIGEST256_LEN,
+ cons1_hash_hex, HEX_DIGEST256_LEN) != DIGEST256_LEN ||
+ base16_decode(cons2_hash, DIGEST256_LEN,
+ cons2_hash_hex, HEX_DIGEST256_LEN) != DIGEST256_LEN) {
+ log_info(LD_CONSDIFF, "The provided consensus diff includes "
+ "malformed digests.");
+ goto error_cleanup;
+ }
+
+ if (digest1_out) {
+ memcpy(digest1_out, cons1_hash, DIGEST256_LEN);
+ }
+ if (digest2_out) {
+ memcpy(digest2_out, cons2_hash, DIGEST256_LEN);
+ }
+
+ SMARTLIST_FOREACH(hash_words, char *, cp, tor_free(cp));
+ smartlist_free(hash_words);
+ return 0;
+
+ error_cleanup:
+
+ if (hash_words) {
+ SMARTLIST_FOREACH(hash_words, char *, cp, tor_free(cp));
+ smartlist_free(hash_words);
+ }
+ return 1;
+}
+
+/** Apply the consensus diff to the given consensus and return a new
+ * consensus, also as a line-based smartlist. Will return NULL if the diff
+ * could not be applied. Neither the consensus nor the diff are modified in
+ * any way, so it's up to the caller to free their resources.
+ */
+char *
+consdiff_apply_diff(const smartlist_t *cons1,
+ const smartlist_t *diff,
+ const consensus_digest_t *digests1)
+{
+ smartlist_t *cons2 = NULL;
+ char *cons2_str = NULL;
+ char e_cons1_hash[DIGEST256_LEN];
+ char e_cons2_hash[DIGEST256_LEN];
+
+ if (consdiff_get_digests(diff, e_cons1_hash, e_cons2_hash) != 0) {
+ goto error_cleanup;
+ }
+
+ /* See that the consensus that was given to us matches its hash. */
+ if (!consensus_digest_eq(digests1->sha3_256,
+ (const uint8_t*)e_cons1_hash)) {
+ char hex_digest1[HEX_DIGEST256_LEN+1];
+ char e_hex_digest1[HEX_DIGEST256_LEN+1];
+ log_warn(LD_CONSDIFF, "Refusing to apply consensus diff because "
+ "the base consensus doesn't match the digest as found in "
+ "the consensus diff header.");
+ base16_encode(hex_digest1, HEX_DIGEST256_LEN+1,
+ (const char *)digests1->sha3_256, DIGEST256_LEN);
+ base16_encode(e_hex_digest1, HEX_DIGEST256_LEN+1,
+ e_cons1_hash, DIGEST256_LEN);
+ log_warn(LD_CONSDIFF, "Expected: %s; found: %s",
+ hex_digest1, e_hex_digest1);
+ goto error_cleanup;
+ }
+
+ /* Grab the ed diff and calculate the resulting consensus. */
+ /* Skip the first two lines. */
+ cons2 = apply_ed_diff(cons1, diff, 2);
+
+ /* ed diff could not be applied - reason already logged by apply_ed_diff. */
+ if (!cons2) {
+ goto error_cleanup;
+ }
+
+ cons2_str = consensus_join_lines(cons2);
+
+ consensus_digest_t cons2_digests;
+ if (consensus_compute_digest(cons2_str, strlen(cons2_str),
+ &cons2_digests) < 0) {
+ /* LCOV_EXCL_START -- digest can't fail */
+ log_warn(LD_CONSDIFF, "Could not compute digests of the consensus "
+ "resulting from applying a consensus diff.");
+ goto error_cleanup;
+ /* LCOV_EXCL_STOP */
+ }
+
+ /* See that the resulting consensus matches its hash. */
+ if (!consensus_digest_eq(cons2_digests.sha3_256,
+ (const uint8_t*)e_cons2_hash)) {
+ log_warn(LD_CONSDIFF, "Refusing to apply consensus diff because "
+ "the resulting consensus doesn't match the digest as found in "
+ "the consensus diff header.");
+ char hex_digest2[HEX_DIGEST256_LEN+1];
+ char e_hex_digest2[HEX_DIGEST256_LEN+1];
+ base16_encode(hex_digest2, HEX_DIGEST256_LEN+1,
+ (const char *)cons2_digests.sha3_256, DIGEST256_LEN);
+ base16_encode(e_hex_digest2, HEX_DIGEST256_LEN+1,
+ e_cons2_hash, DIGEST256_LEN);
+ log_warn(LD_CONSDIFF, "Expected: %s; found: %s",
+ hex_digest2, e_hex_digest2);
+ goto error_cleanup;
+ }
+
+ goto done;
+
+ error_cleanup:
+ tor_free(cons2_str); /* Sets it to NULL */
+
+ done:
+ if (cons2) {
+ smartlist_free(cons2);
+ }
+
+ return cons2_str;
+}
+
+/** Any consensus line longer than this means that the input is invalid. */
+#define CONSENSUS_LINE_MAX_LEN (1<<20)
+
+/**
+ * Helper: For every NL-terminated line in <b>s</b>, add a cdline referring to
+ * that line (without trailing newline) to <b>out</b>. Return -1 if there are
+ * any non-NL terminated lines; 0 otherwise.
+ *
+ * Unlike tor_split_lines, this function avoids ambiguity on its
+ * handling of a final line that isn't NL-terminated.
+ *
+ * All cdline_t objects are allocated in the provided memarea. Strings
+ * are not copied: if <b>s</b> changes or becomes invalid, then all
+ * generated cdlines will become invalid.
+ */
+STATIC int
+consensus_split_lines(smartlist_t *out,
+ const char *s, size_t len,
+ memarea_t *area)
+{
+ const char *end_of_str = s + len;
+
+ while (s < end_of_str) {
+ const char *eol = memchr(s, '\n', end_of_str - s);
+ if (!eol) {
+ /* File doesn't end with newline. */
+ return -1;
+ }
+ if (eol - s > CONSENSUS_LINE_MAX_LEN) {
+ /* Line is far too long. */
+ return -1;
+ }
+ cdline_t *line = memarea_alloc(area, sizeof(cdline_t));
+ line->s = s;
+ line->len = (uint32_t)(eol - s);
+ smartlist_add(out, line);
+ s = eol+1;
+ }
+ return 0;
+}
+
+/** Given a list of cdline_t, return a newly allocated string containing
+ * all of the lines, terminated with NL, concatenated.
+ *
+ * Unlike smartlist_join_strings(), avoids lossy operations on empty
+ * lists. */
+static char *
+consensus_join_lines(const smartlist_t *inp)
+{
+ size_t n = 0;
+ SMARTLIST_FOREACH(inp, const cdline_t *, cdline, n += cdline->len + 1);
+ n += 1;
+ char *result = tor_malloc(n);
+ char *out = result;
+ SMARTLIST_FOREACH_BEGIN(inp, const cdline_t *, cdline) {
+ memcpy(out, cdline->s, cdline->len);
+ out += cdline->len;
+ *out++ = '\n';
+ } SMARTLIST_FOREACH_END(cdline);
+ *out++ = '\0';
+ tor_assert(out == result+n);
+ return result;
+}
+
+/** Given two consensus documents, try to compute a diff between them. On
+ * success, retun a newly allocated string containing that diff. On failure,
+ * return NULL. */
+char *
+consensus_diff_generate(const char *cons1, size_t cons1len,
+ const char *cons2, size_t cons2len)
+{
+ consensus_digest_t d1, d2;
+ smartlist_t *lines1 = NULL, *lines2 = NULL, *result_lines = NULL;
+ int r1, r2;
+ char *result = NULL;
+
+ r1 = consensus_compute_digest_as_signed(cons1, cons1len, &d1);
+ r2 = consensus_compute_digest(cons2, cons2len, &d2);
+ if (BUG(r1 < 0 || r2 < 0))
+ return NULL; // LCOV_EXCL_LINE
+
+ memarea_t *area = memarea_new();
+ lines1 = smartlist_new();
+ lines2 = smartlist_new();
+ if (consensus_split_lines(lines1, cons1, cons1len, area) < 0)
+ goto done;
+ if (consensus_split_lines(lines2, cons2, cons2len, area) < 0)
+ goto done;
+
+ result_lines = consdiff_gen_diff(lines1, lines2, &d1, &d2, area);
+
+ done:
+ if (result_lines) {
+ result = consensus_join_lines(result_lines);
+ smartlist_free(result_lines);
+ }
+
+ memarea_drop_all(area);
+ smartlist_free(lines1);
+ smartlist_free(lines2);
+
+ return result;
+}
+
+/** Given a consensus document and a diff, try to apply the diff to the
+ * consensus. On success return a newly allocated string containing the new
+ * consensus. On failure, return NULL. */
+char *
+consensus_diff_apply(const char *consensus,
+ size_t consensus_len,
+ const char *diff,
+ size_t diff_len)
+{
+ consensus_digest_t d1;
+ smartlist_t *lines1 = NULL, *lines2 = NULL;
+ int r1;
+ char *result = NULL;
+ memarea_t *area = memarea_new();
+
+ r1 = consensus_compute_digest_as_signed(consensus, consensus_len, &d1);
+ if (BUG(r1 < 0))
- return NULL; // LCOV_EXCL_LINE
++ goto done;
+
+ lines1 = smartlist_new();
+ lines2 = smartlist_new();
+ if (consensus_split_lines(lines1, consensus, consensus_len, area) < 0)
+ goto done;
+ if (consensus_split_lines(lines2, diff, diff_len, area) < 0)
+ goto done;
+
+ result = consdiff_apply_diff(lines1, lines2, &d1);
+
+ done:
+ smartlist_free(lines1);
+ smartlist_free(lines2);
+ memarea_drop_all(area);
+
+ return result;
+}
+
+/** Return true iff, based on its header, <b>document</b> is likely
+ * to be a consensus diff. */
+int
+looks_like_a_consensus_diff(const char *document, size_t len)
+{
+ return (len >= strlen(ns_diff_version) &&
+ fast_memeq(document, ns_diff_version, strlen(ns_diff_version)));
+}
1
0

[translation/support-portal] Update translations for support-portal
by translation@torproject.org 26 Mar '19
by translation@torproject.org 26 Mar '19
26 Mar '19
commit d43601434b3ffa8072aa663cef2e88a178f15666
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 06:50:53 2019 +0000
Update translations for support-portal
---
contents+ar.po | 12 +++++-----
contents+tr.po | 71 ++++++++++++++++++++++++++++------------------------------
2 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/contents+ar.po b/contents+ar.po
index e2774697c..f4695c2b9 100644
--- a/contents+ar.po
+++ b/contents+ar.po
@@ -96,7 +96,7 @@ msgstr ""
#: https//support.torproject.org/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en.lrquestion.description)
msgid "* Click the blue 'Join Team' button on the far right:"
-msgstr ""
+msgstr "* انقر على زر \"الانضمام إلى فريق\" الأزرق في أقصى اليمين:"
#: https//support.torproject.org/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en.lrquestion.description)
@@ -107,7 +107,7 @@ msgstr "<img class=\"col-md-6\" src=\"../../static/images/tr3.png\">"
#: (content/becoming-tor-translator/contents+en.lrquestion.description)
msgid ""
"* Select the language you would like to translate from the dropdown menu:"
-msgstr ""
+msgstr "*اختر لغة الترجمة من القائمة المنسدلة:"
#: https//support.torproject.org/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en.lrquestion.description)
@@ -117,7 +117,7 @@ msgstr "<img class=\"col-md-6\" src=\"../../static/images/tr4.png\">"
#: https//support.torproject.org/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en.lrquestion.description)
msgid "* A notification will now show up on the top of the page like so:"
-msgstr ""
+msgstr "إشعار سيظهر في أعلى الصفحة كالتالي:"
#: https//support.torproject.org/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en.lrquestion.description)
@@ -144,7 +144,7 @@ msgstr ""
#: https//support.torproject.org/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en.lrquestion.description)
msgid "Thanks for your interest in helping the project!"
-msgstr ""
+msgstr "شكراً لإهتمامك بالمساهمة في المشروع!"
#: https//support.torproject.org/faq/ (content/faq/contents+en.lrtopic.title)
msgid "Most Frequently Asked Questions"
@@ -5431,6 +5431,8 @@ msgid ""
"Trademark, copyright notices, and rules for use by third parties can be "
"found in our "
msgstr ""
+"العلامات التجارية، إشعارات حقوق الطبع والنشر والقواعد للاستخدام من قبل أطراف"
+" ثالثة يمكن العثور عليها في"
#: templates/layout.html:8
msgid "Tor Project | Support"
@@ -5454,4 +5456,4 @@ msgstr "الموضوعات"
#: templates/macros/question.html:13
msgid "Permalink"
-msgstr ""
+msgstr "رابط ثابت"
diff --git a/contents+tr.po b/contents+tr.po
index 113fdd6d1..dbe811839 100644
--- a/contents+tr.po
+++ b/contents+tr.po
@@ -5422,7 +5422,7 @@ msgstr ""
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
msgid "### Sybil attack"
-msgstr "### Sybil attack"
+msgstr "### Sybil attack, Sybil saldırısı"
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -5957,11 +5957,12 @@ msgid ""
" identifier if only a small number of users have the same path length as "
"you."
msgstr ""
-"3 üzerinde yolların kullanılması anonimliği olumsuz etkileyebilir. Öncelikle"
-" <mark><a href=\"https://www.freehaven.net/anonbib/#ccs07-doa\">Denial of "
-"Security</a></mark> saldırılarının yapılmasını kolaylaştırır. Bunun yanında "
-"sizinle aynı uzunlukta bir yol kullanan az sayıda kullanıcı varsa bu bilgi "
-"bir belirteç olarak kullanılabilir."
+"Ayrıca, 3 düğümden uzun yolların kullanılması anonim kalmayı da olumsuz "
+"etkileyebilir. Öncelikle <mark><a "
+"href=\"https://www.freehaven.net/anonbib/#ccs07-doa\">Denial of "
+"Security</a></mark> saldırılarının yapılmasını kolaylaştırır. Ayrıca sizinle"
+" aynı yol uzunluğunu kullanan kullanıcı sayısı az ise bu bilgi kim "
+"olduğunuzu belirlemek için kullanılabilir."
#: https//support.torproject.org/misc/share-files-anonymously-through-tor/
#: (content/misc/misc-12/contents+en.lrquestion.title)
@@ -6020,7 +6021,7 @@ msgstr "Tor Projesine nasıl bağış yapabilirim?"
#: https//support.torproject.org/misc/donate-tor-project/
#: (content/misc/misc-15/contents+en.lrquestion.description)
msgid "Thank you for your support!"
-msgstr "Destek olduğunuz için teşekkürler!"
+msgstr "Desteğiniz için teşekkür ederiz!"
#: https//support.torproject.org/misc/donate-tor-project/
#: (content/misc/misc-15/contents+en.lrquestion.description)
@@ -6028,8 +6029,8 @@ msgid ""
"You can find more information about donating on our <mark><a "
"href=\"https://donate.torproject.org/donor-faq\">donor FAQ</a></mark>."
msgstr ""
-"Destek olmak için <mark><a href=\"https://donate.torproject.org/donor-"
-"faq\">Bağış Hakkında SSS</a></mark> bölümüne bakabilirsiniz."
+"Bağış yapmak için <mark><a href=\"https://donate.torproject.org/donor-"
+"faq\">Bağış SSS</a></mark> bölümüne bakabilirsiniz."
#: https//support.torproject.org/misc/prevent-bad-people-doing-bad-things-with-tor/
#: (content/misc/misc-2/contents+en.lrquestion.title)
@@ -6044,8 +6045,8 @@ msgid ""
"Tor is designed to defend human rights and privacy by preventing anyone from"
" censoring things, even us."
msgstr ""
-"Tor insan hakları ve kişisel gizliliğin korunmasını sağlamak ve bir şeylerin"
-" sansürlenmesinin önüne geçmek için tasarlanmıştır."
+"Tor insan hakları ve kişisel gizliliğin korunmasını sağlamak ve birilerinin "
+"bir şeyleri sansürlenmesini engellemek için tasarlanmıştır."
#: https//support.torproject.org/misc/prevent-bad-people-doing-bad-things-with-tor/
#: (content/misc/misc-2/contents+en.lrquestion.description)
@@ -6057,8 +6058,8 @@ msgid ""
msgstr ""
"Tor kullanan bazı insanların korkunç şeyler yapmasından nefret ediyoruz. "
"Ancak insan hakları aktivistleri, gazeteciler, taciz kurbanları gibi diğer "
-"kullanıcıları açığa çıkarabilecek verileri toplamamız gerekeceğinden kötü "
-"niyetli kişilerden kurtulmak için de bir şey yapamıyoruz."
+"kullanıcıları da açığa çıkarabilecek verileri toplamamız gerekeceğinden, "
+"kötü niyetli kişilerden kurtulmak için de bir önlem alamıyoruz."
#: https//support.torproject.org/misc/prevent-bad-people-doing-bad-things-with-tor/
#: (content/misc/misc-2/contents+en.lrquestion.description)
@@ -6067,7 +6068,7 @@ msgid ""
"adding a backdoor to the software, which would open up our vulnerable users "
"to attacks from bad regimes and other adversaries."
msgstr ""
-"Belirli kişilerin Tor kullanmasını engellemek istersek yazılıma bir arka "
+"Belirli kişilerin Tor kullanmasını engellemek istersek, yazılıma bir arka "
"kapı eklememiz gerekir. Ancak bu kapı kötü niyetli yönetimler ve kuruluşlar "
"tarafından kullanıcılarımıza saldırmak için kullanılabilir."
@@ -6082,8 +6083,8 @@ msgid ""
"Tor is funded by a number of different sponsors including US federal "
"agencies, private foundations, and individual donors."
msgstr ""
-"Tor Projesine ABD federal kuruluşları, özel vakıflar ve kişiler gibi çeşitli"
-" destekçiler bağış yapmaktadır."
+"Tor Projesine Birleşik Devletlerdeki bazı federal kuruluşlar, özel vakıflar "
+"ve kişiler gibi çeşitli destekçiler bağış yaparak destek oluyor."
#: https//support.torproject.org/misc/tor-funding/
#: (content/misc/misc-3/contents+en.lrquestion.description)
@@ -6094,11 +6095,11 @@ msgid ""
"href=\"https://blog.torproject.org/category/tags/form-990\">blog "
"posts</a></mark> on our financial reports."
msgstr ""
-"<mark><a "
-"href=\"https://www.torproject.org/about/sponsors.html.en\">Sponsorlarımızın "
-"listesine</a></mark> ve finansal raporlarımız hakkındaki <mark><a "
+"Ayrıntılı bilgi almak için <mark><a "
+"href=\"https://www.torproject.org/about/sponsors.html.en\">destekçi "
+"listemize</a></mark> ve mali durumumuz hakkındaki <mark><a "
"href=\"https://blog.torproject.org/category/tags/form-990\">blog "
-"iletilerine</a></mark> bakabilirsiniz."
+"iletilerimize</a></mark> bakabilirsiniz."
#: https//support.torproject.org/misc/tor-funding/
#: (content/misc/misc-3/contents+en.lrquestion.description)
@@ -6126,7 +6127,7 @@ msgstr "Tor ile BitTorrent kullanabilir miyim?"
#: https//support.torproject.org/misc/tor-bittorrent/
#: (content/misc/misc-4/contents+en.lrquestion.description)
msgid "We do not recommend using Tor with BitTorrent."
-msgstr "Tor uygulamasını BitTorrent ile birlikte kullanmanız önerilmez."
+msgstr "Tor uygulamasının BitTorrent ile birlikte kullanılmasını önermiyoruz."
#: https//support.torproject.org/misc/tor-bittorrent/
#: (content/misc/misc-4/contents+en.lrquestion.description)
@@ -6161,9 +6162,8 @@ msgid ""
"ransom they're demanding from you."
msgstr ""
"Bu zararlı yazılım Tor Projesi tarafından oluşturulmadı. Bu zararlı yazılımı"
-" üretenler, sizden isteyecekleri fidye için kendileri ile anonim olarak "
-"iletişim kurulabilmesi amacıyla Tor Browser uygulamasını indirmenizi "
-"istiyorlar."
+" üretenler, sizden isteyecekleri fidye için anonim kalmak amacıyla iletişim "
+"kurabilmeniz için Tor Browser uygulamasını indirmenizi istiyorlar."
#: https//support.torproject.org/misc/someone-asks-to-download-tor-browser-to-unlock-my-files/
#: (content/misc/misc-5/contents+en.lrquestion.description)
@@ -6171,9 +6171,8 @@ msgid ""
"If this is your first introduction to Tor Browser, we understand that you "
"might think we're bad people who enable even worse people."
msgstr ""
-"Tor Browser ile ilk kez karşılaşıyorsanız, çok kötü niyetli kişilere olanak "
-"sağlayan kötü niyetli kişiler olduğumuzu düşünebilirsiniz. Bu durumu "
-"anlıyoruz."
+"Tor Browser ile ilk kez karşılaşıyorsanız, çok kötü niyetli kişilerin yolunu"
+" açan kötü niyetli kişiler olduğumuzu düşünebilirsiniz. Bu durumu anlıyoruz."
#: https//support.torproject.org/misc/someone-asks-to-download-tor-browser-to-unlock-my-files/
#: (content/misc/misc-5/contents+en.lrquestion.description)
@@ -6186,9 +6185,9 @@ msgid ""
msgstr ""
"Ancak lütfen uygulamamızın her gün çok farklı amaçlarla insan hakları "
"aktivistleri, gazeteciler, taciz kurbanları, yolsuzlukları açığa çıkaranlar,"
-" kolluk kuvvetleri ve pek çok diğer kişi tarafından kullanıldığını da göz "
-"önüne alın. Maalesef uygulamamızın bu gruplar için sağladığı koruma suçlular"
-" ve kötü niyetli yazılım geliştirenler tarafından da kullanılıyor."
+" kolluk kuvvetleri gibi pek çok diğer kişi tarafından kullanıldığını da göz "
+"önüne alın. Maalesef uygulamamızın bu gruplar için sağladığı koruma, "
+"suçlular ve kötü niyetli yazılım geliştirenler tarafından da kullanılıyor."
#: https//support.torproject.org/misc/someone-asks-to-download-tor-browser-to-unlock-my-files/
#: (content/misc/misc-5/contents+en.lrquestion.description)
@@ -6207,9 +6206,7 @@ msgstr "Tor günlük kayıtları tutuyor mu?"
#: https//support.torproject.org/misc/does-tor-keep-logs/
#: (content/misc/misc-6/contents+en.lrquestion.description)
msgid "Tor doesn't keep any logs that could identify a particular user."
-msgstr ""
-"Tor sizin kim olduğunuzun anlaşılmasını sağlayacak herhangi bir günlük kaydı"
-" tutmaz."
+msgstr "Tor kim olduğunuzu açığa çıkaracak herhangi bir günlük kaydı tutmaz."
#: https//support.torproject.org/misc/does-tor-keep-logs/
#: (content/misc/misc-6/contents+en.lrquestion.description)
@@ -6219,8 +6216,8 @@ msgid ""
"Metrics</a></mark>."
msgstr ""
"<mark><a href=\"https://metrics.torproject.org/\">Tor "
-"İstatistikleri</a></mark> bölümünde görebileceğiniz gibi yalnız ağın nasıl "
-"çalıştığı ile ilgili bazı güvenli ölçümler yapıyoruz."
+"İstatistikleri</a></mark> bölümünde görebileceğiniz gibi yalnız ağın "
+"çalışması ile ilgili bazı güvenli ölçümler yapıyoruz."
#: https//support.torproject.org/misc/does-tor-project-offer-email-or-privacy-protecting-web-services/
#: (content/misc/misc-7/contents+en.lrquestion.title)
@@ -6243,9 +6240,9 @@ msgid ""
"href=\"https://www.torproject.org/projects/projects.html.en\">projects "
"page</a></mark>."
msgstr ""
-"Yazılım projelerimizin listesine <mark><a "
+"Tüm yazılım projelerimizi <mark><a "
"href=\"https://www.torproject.org/projects/projects.html.en\">projeler "
-"sayfasından</a></mark> bakabilirsiniz."
+"sayfamızda</a></mark> görebilirsiniz."
#: https//support.torproject.org/misc/using-tor-logo/
#: (content/misc/misc-8/contents+en.lrquestion.title)
1
0

[translation/tbmanual-contentspot] Update translations for tbmanual-contentspot
by translation@torproject.org 26 Mar '19
by translation@torproject.org 26 Mar '19
26 Mar '19
commit f25259c83e10cc434a3c3fa84f3c665b340e6ae6
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 06:47:53 2019 +0000
Update translations for tbmanual-contentspot
---
contents+ar.po | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/contents+ar.po b/contents+ar.po
index c921460a8..de2c80daa 100644
--- a/contents+ar.po
+++ b/contents+ar.po
@@ -497,6 +497,8 @@ msgid ""
"Then, select 'Provide a bridge I know' and enter each bridge address on a "
"separate line."
msgstr ""
+"في نافذة Tor Network Settings (إعدادات شبكة Tor) ، حدد \"Tor يخضع للرقابة في"
+" بلدي\". ثم ، حدد \"توفير جسر أعرفه\" وأدخل كل عنوان جسر على سطر منفصل."
#: https//tb-manual.torproject.org/en-US/bridges/
#: (content/bridges/contents+en-US.lrtopic.body)
@@ -513,6 +515,8 @@ msgid ""
"Click “OK” to save your settings. Using bridges may slow down the connection"
" compared to using ordinary Tor relays."
msgstr ""
+"انقر فوق \"موافق\" لحفظ الإعدادات الخاصة بك. قد يؤدي استخدام الجسور إلى "
+"إبطاء الاتصال مقارنة باستخدام مرحلات Tor العادية."
#: https//tb-manual.torproject.org/en-US/bridges/
#: (content/bridges/contents+en-US.lrtopic.body)
@@ -652,6 +656,10 @@ msgid ""
"Web Services; meek-azure makes it look like you are using a Microsoft web "
"site; and meek-google makes it look like you are using Google search."
msgstr ""
+"تجعل جميع وسائل نقل meek تبدو كما لو كنت تتصفح موقع ويب رئيسي بدلاً من "
+"استخدام Tor. يجعل meek-amazon الأمر يبدو أنك تستخدم خدمات الويب من Amazon ؛ "
+"يجعل meek-azure الأمر يبدو أنك تستخدم موقع Microsoft على الويب ؛ و meek-"
+"google يجعل الأمر يبدو كما لو كنت تستخدم بحث Google."
#: https//tb-manual.torproject.org/en-US/transports/
#: (content/transports/contents+en-US.lrtopic.body)
@@ -678,7 +686,7 @@ msgstr "</table>"
#: https//tb-manual.torproject.org/en-US/transports/
#: (content/transports/contents+en-US.lrtopic.body)
msgid "##### How to use pluggable transports"
-msgstr ""
+msgstr "##### كيفية استخدام وسائل النقل القابلة للتوصيل"
#: https//tb-manual.torproject.org/en-US/transports/
#: (content/transports/contents+en-US.lrtopic.body)
@@ -686,11 +694,13 @@ msgid ""
"To use a pluggable transport, first click the onion icon to the left of the "
"URL bar, or click 'Configure' when starting Tor Browser for the first time."
msgstr ""
+"لاستخدام وسيلة نقل قابلة للتوصيل ، انقر أولاً فوق رمز البصل/اونيون على يسار "
+"شريط URL ، أو انقر فوق \"تكوين\" عند بدء تشغيل متصفح Tor لأول مرة."
#: https//tb-manual.torproject.org/en-US/transports/
#: (content/transports/contents+en-US.lrtopic.body)
msgid "Next, select 'Tor Network Settings' from the drop-down menu."
-msgstr ""
+msgstr "بعد ذلك ، حدد \"إعدادات شبكة Tor\" من القائمة المنسدلة."
#: https//tb-manual.torproject.org/en-US/transports/
#: (content/transports/contents+en-US.lrtopic.body)
@@ -698,6 +708,8 @@ msgid ""
"In the window that appears, check 'Tor is censored in my country,' then "
"click 'Select a built-in bridge.'"
msgstr ""
+"في النافذة التي تظهر ، حدد \"Tor تخضع للرقابة في بلدي\" ، ثم انقر فوق "
+"\"تحديد جسر مضمن\"."
#: https//tb-manual.torproject.org/en-US/transports/
#: (content/transports/contents+en-US.lrtopic.body)
@@ -705,6 +717,7 @@ msgid ""
"From the drop-down menu, select whichever pluggable transport you'd like to "
"use."
msgstr ""
+"من القائمة المنسدلة ، حدد أي وسيلة نقل قابلة للتوصيل ترغب في استخدامها."
#: https//tb-manual.torproject.org/en-US/transports/
#: (content/transports/contents+en-US.lrtopic.body)
@@ -721,6 +734,8 @@ msgid ""
"Once you've selected the pluggable transport you'd like to use, click 'OK' "
"to save your settings."
msgstr ""
+"بمجرد تحديد النقل القابل للتوصيل الذي تريد استخدامه ، انقر فوق \"موافق\" "
+"لحفظ الإعدادات."
#: https//tb-manual.torproject.org/en-US/circumvention/
#: (content/circumvention/contents+en-US.lrtopic.title)
@@ -751,7 +766,7 @@ msgstr ""
#: (content/circumvention/contents+en-US.lrtopic.body)
msgid ""
"Tor Browser currently has four pluggable transport options to choose from."
-msgstr ""
+msgstr "يحتوي متصفح Tor حاليًا على أربعة خيارات نقل قابلة للاختيار من بينها."
#: https//tb-manual.torproject.org/en-US/circumvention/
#: (content/circumvention/contents+en-US.lrtopic.body)
@@ -764,6 +779,8 @@ msgid ""
"To use pluggable transports, click 'Configure' in the Tor Launcher window "
"that appears when you first run Tor Browser."
msgstr ""
+"لاستخدام وسائل النقل القابلة للتوصيل ، انقر فوق \"تكوين\" في نافذة Tor "
+"Launcher التي تظهر عند تشغيل Tor Browser لأول مرة."
#: https//tb-manual.torproject.org/en-US/circumvention/
#: (content/circumvention/contents+en-US.lrtopic.body)
@@ -772,6 +789,9 @@ msgid ""
"clicking on the onion icon to the left of the address bar, then selecting "
"'Tor Network Settings'."
msgstr ""
+"يمكنك أيضًا تهيئة وسائل النقل القابلة للتوصيل أثناء تشغيل متصفح Tor بالضغط "
+"على أيقونة البصل/اونيون على يسار شريط العنوان ، ثم تحديد \"إعدادات شبكة "
+"Tor\"."
#: https//tb-manual.torproject.org/en-US/circumvention/
#: (content/circumvention/contents+en-US.lrtopic.body)
@@ -2026,7 +2046,7 @@ msgstr ""
#: https//tb-manual.torproject.org/en-US/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en-US.lrtopic.body)
msgid "* Click the blue 'Join Team' button on the far right:"
-msgstr ""
+msgstr "* انقر على زر \"الانضمام إلى فريق\" الأزرق في أقصى اليمين:"
#: https//tb-manual.torproject.org/en-US/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en-US.lrtopic.body)
@@ -2037,7 +2057,7 @@ msgstr "<img class=\"col-md-6\" src=\"../../static/images/tr3.png\">"
#: (content/becoming-tor-translator/contents+en-US.lrtopic.body)
msgid ""
"* Select the language you would like to translate from the dropdown menu:"
-msgstr ""
+msgstr "*اختر لغة الترجمة من القائمة المنسدلة:"
#: https//tb-manual.torproject.org/en-US/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en-US.lrtopic.body)
@@ -2047,7 +2067,7 @@ msgstr "<img class=\"col-md-6\" src=\"../../static/images/tr4.png\">"
#: https//tb-manual.torproject.org/en-US/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en-US.lrtopic.body)
msgid "* A notification will now show up on the top of the page like so:"
-msgstr ""
+msgstr "إشعار سيظهر في أعلى الصفحة كالتالي:"
#: https//tb-manual.torproject.org/en-US/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en-US.lrtopic.body)
@@ -2074,7 +2094,7 @@ msgstr ""
#: https//tb-manual.torproject.org/en-US/becoming-tor-translator/
#: (content/becoming-tor-translator/contents+en-US.lrtopic.body)
msgid "Thanks for your interest in helping the project!"
-msgstr ""
+msgstr "شكراً لإهتمامك بالمساهمة في المشروع!"
#: templates/footer.html:5
msgid "Our mission:"
@@ -2094,7 +2114,7 @@ msgstr "اشترك في رسالتنا للمستجدات"
#: templates/footer.html:25
msgid "Get monthly updates and opportunities from the Tor Project"
-msgstr ""
+msgstr "احصل على تحديثات شهرية وفرص من مشروع تور"
#: templates/footer.html:26
msgid "Sign up"
@@ -2105,6 +2125,8 @@ msgid ""
"Trademark, copyright notices, and rules for use by third parties can be "
"found in our "
msgstr ""
+"العلامات التجارية، إشعارات حقوق الطبع والنشر والقواعد للاستخدام من قبل أطراف"
+" ثالثة يمكن العثور عليها في"
#: templates/layout.html:8
msgid "Tor Project | Tor Browser Manual"
@@ -2128,4 +2150,4 @@ msgstr "الموضوعات"
#: templates/macros/topic.html:18
msgid "Permalink"
-msgstr ""
+msgstr "رابط ثابت"
1
0

[translation/donatepages-messagespot_completed] Update translations for donatepages-messagespot_completed
by translation@torproject.org 26 Mar '19
by translation@torproject.org 26 Mar '19
26 Mar '19
commit c26cd4977aeacee63bccf1f8185cf8e524cf64eb
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 06:45:44 2019 +0000
Update translations for donatepages-messagespot_completed
---
locale/tr/LC_MESSAGES/messages.po | 56 +++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/locale/tr/LC_MESSAGES/messages.po b/locale/tr/LC_MESSAGES/messages.po
index c3df22ea5..eb318e166 100644
--- a/locale/tr/LC_MESSAGES/messages.po
+++ b/locale/tr/LC_MESSAGES/messages.po
@@ -11,7 +11,6 @@
# Lale Fatoş Tunçman <latuna63(a)gmail.com>, 2019
# Taha Karadoğan <tahakaradogan(a)gmail.com>, 2019
# Hasan Tayyar BESIK <tayyar.besik(a)gmail.com>, 2019
-# Tmp341, 2019
# ilkeryus <ilkeryus(a)gmail.com>, 2019
# T. E. Kalayci <tekrei(a)gmail.com>, 2019
# Kaya Zeren <kayazeren(a)gmail.com>, 2019
@@ -359,9 +358,9 @@ msgid ""
"privacy-enhancing browser for mobile devices and making it easier for third-"
"party developers to integrate Tor into their applications."
msgstr ""
-"Desteğiniz ve cömert Mozilla hediye katlama fonları sayesinde, mobil "
-"aygıtlar için daha güvenli ve gizliliği arttıracak bir tarayıcı "
-"geliştirmenin yanında üçüncü taraf geliştiricilerin uygulamalarını Tor ile "
+"Desteğiniz ve cömert Mozilla bağış katlama fonları sayesinde, mobil aygıtlar"
+" için daha güvenli ve gizliliği arttıracak bir tarayıcı geliştirmenin "
+"yanında üçüncü taraf geliştiricilerin uygulamalarını Tor ile "
"bütünleştirmesini kolaylaştırmak gibi iddialı projelere girişebileceğiz. ."
#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:61
@@ -462,7 +461,7 @@ msgstr "Toplam Bağış Tutarı"
#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:159
msgid "Total Raised with Mozilla's Match"
-msgstr "Mozilla Kampanyası ile Toplam Tutar"
+msgstr "Mozilla Bağış Katlama Kampanyası ile Toplam Tutar"
#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:170
#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:176
@@ -744,7 +743,7 @@ msgstr ""
#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:651
#: tmp/cache_locale/9f/9f870858aaf6c5a7c94ea6a959618fbe485cbfd16174993d34a8e370a4567526.php:84
msgid "Mozilla will match your gift and double your impact."
-msgstr "Mozilla eşit miktarda bir bağış yapacak ve hediyeniz katlanacak."
+msgstr "Mozilla eşit miktarda bir bağış yapacak ve bağışınız katlanacak."
#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:61
msgid "Thank you for your support of the Tor Project."
@@ -1772,7 +1771,7 @@ msgstr "Evet"
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:496
msgid "Does Tor Project accept matching donations?"
-msgstr "Tor Project eşleşen bağışları kabul eder mi? "
+msgstr "Tor Projesi bağış katlama kampanyası yapıyor mu? "
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:500
msgid ""
@@ -1780,9 +1779,9 @@ msgid ""
"Verizon, Red Hat, many universities, and others-- will match donations made "
"by their employees."
msgstr ""
-"Evet! Çoğu şirket Google, Microsoft, eBay, PayPal, Apple, Verizon, Red Hat, "
-"çoğu üniversite ve diğerleri gibi çalışanları tarafından yapılan bağışları "
-"karşılaştıracaktır."
+"Evet! Google, Microsoft, eBay, PayPal, Apple, Verizon, Red Hat gibi "
+"şirketler, pek çok üniversite ve diğer kuruluşlar çalışanlarının yaptıkları "
+"bağış kadar bağış yaparak toplam bağış tutarını katlıyor."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:502
msgid ""
@@ -1791,39 +1790,38 @@ msgid ""
" <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.matchinggifts.com/rit/\">https://www.matchinggifts.com/rit/</a>."
msgstr ""
-"Sizin şirketinizin bağışları karşılaştırdığını bulmanın en hızlı yolu "
-"genellikle sizin HR departmanınızı kontrol ederek olur ya da siz şirket "
-"adınızı <a class=\"hyperlinks links\" target=\"_blank\" "
+"Kuruluşunuzun bağış katlama kampanyası yapıp yapmadığını genellikle İK "
+"bölümünden öğrenebilirsiniz. Ayrıca kuruluşunuzun adının <a "
+"class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.matchinggifts.com/rit/\"> "
-"https://www.matchinggifts.com/rit/</a>'te arayabilirsiniz. "
+"https://www.matchinggifts.com/rit/</a>sayfasında yer alıp almadığına da "
+"bakabilirsiniz. "
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:504
msgid ""
"If your company isn't currently set up to match donations to the Tor "
"Project, we would be happy to help with the paperwork."
msgstr ""
-"Eğer şirketiniz, şu an için Tor Projesine eş bağışını düzenlemediyse, kağıt "
-"işlerinde yardım etmekten mutluluk duyarız."
+"Kuruluşunuz şu anda Tor Projesi için bir bağış katlama kampanyası "
+"yapmıyorsa, gerekli kağıt işlerine yardımcı olmaktan mutluluk duyarız."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:506
msgid ""
"If you want help figuring out the process, write us at <span "
"class=\"email\">giving(at)torproject.org</a>."
msgstr ""
-"Süreçle ilgili yardıma ihtiyacınız varsa bize <span "
+"Süreçle ilgili yardıma gerek duyarsanız bize <span "
"class=\"email\">giving(at)torproject.org</a> adresinden ulaşabilirsiniz."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:512
msgid "Can I become a Tor Project member?"
-msgstr "Tor Projesi'nin bir parçası olabilir miyim?"
+msgstr "Tor Projesine katılabilir miyim?"
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:516
msgid ""
"Right now, we don't have a membership program, but we may set one up in the "
"future."
-msgstr ""
-"Şimdilik herhangi bir üyelik programımız yok, ama ilerleyen zamanlarda bir "
-"tane hazırlama ihtimalimiz var."
+msgstr "Şimdilik herhangi bir üyelik programımız yok. Ancak ileride olabilir."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:518
msgid ""
@@ -1832,10 +1830,10 @@ msgid ""
"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">this is a "
"good place to start</a>."
msgstr ""
-"Tor Projesi'yle ilgilenmek istiyorsanız, <a class=\"hyperlinks links\" "
+"Tor Projesine katkıda bulunmak istiyorsanız, <a class=\"hyperlinks links\" "
"target=\"_blank\" "
-"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">burası "
-"başlamak için iyi bir yerdir</a>."
+"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">buradan "
+"başlayabilirsiniz</a>."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:524
msgid "How can I get a Tor t-shirt or stickers?"
@@ -1951,8 +1949,8 @@ msgid ""
"Your company could match donations made by its employees to the Tor Project"
"--that would be wonderful."
msgstr ""
-"Şirketiniz, Tor Projesine çalışanlarınızın yaptığı bağışlara denk bir bağış "
-"yapabilir, bu mükemmel olur."
+"Kuruluşunuz Tor Projesine çalışanlarının yaptığı kadar bir bağış yaparsa bu "
+"harika olur."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:600
msgid ""
@@ -2042,7 +2040,9 @@ msgstr ""
#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:22
msgid "See if your employer offers employee gift matching"
-msgstr "İşvereniniz çalışanlara hediye katlama olanağı sunar mı"
+msgstr ""
+"Kuruluşunuzun çalışanlarına bağış katlama kampanyası yapıp yapmadığını "
+"öğrenin"
#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:52
msgid "Company"
@@ -2050,7 +2050,7 @@ msgstr "Kuruluş"
#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:60
msgid "Matching Conditions"
-msgstr "Katlama Koşulları"
+msgstr "Bağış Katlama Kampanyası Koşulları"
#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:68
msgid "Contact Information"
1
0

[translation/donatepages-messagespot] Update translations for donatepages-messagespot
by translation@torproject.org 26 Mar '19
by translation@torproject.org 26 Mar '19
26 Mar '19
commit 53340b204bf7b08ba5918cae26590f80d12bf261
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 06:45:37 2019 +0000
Update translations for donatepages-messagespot
---
locale/tr/LC_MESSAGES/messages.po | 56 +++++++++++++++++++--------------------
1 file changed, 28 insertions(+), 28 deletions(-)
diff --git a/locale/tr/LC_MESSAGES/messages.po b/locale/tr/LC_MESSAGES/messages.po
index c3df22ea5..eb318e166 100644
--- a/locale/tr/LC_MESSAGES/messages.po
+++ b/locale/tr/LC_MESSAGES/messages.po
@@ -11,7 +11,6 @@
# Lale Fatoş Tunçman <latuna63(a)gmail.com>, 2019
# Taha Karadoğan <tahakaradogan(a)gmail.com>, 2019
# Hasan Tayyar BESIK <tayyar.besik(a)gmail.com>, 2019
-# Tmp341, 2019
# ilkeryus <ilkeryus(a)gmail.com>, 2019
# T. E. Kalayci <tekrei(a)gmail.com>, 2019
# Kaya Zeren <kayazeren(a)gmail.com>, 2019
@@ -359,9 +358,9 @@ msgid ""
"privacy-enhancing browser for mobile devices and making it easier for third-"
"party developers to integrate Tor into their applications."
msgstr ""
-"Desteğiniz ve cömert Mozilla hediye katlama fonları sayesinde, mobil "
-"aygıtlar için daha güvenli ve gizliliği arttıracak bir tarayıcı "
-"geliştirmenin yanında üçüncü taraf geliştiricilerin uygulamalarını Tor ile "
+"Desteğiniz ve cömert Mozilla bağış katlama fonları sayesinde, mobil aygıtlar"
+" için daha güvenli ve gizliliği arttıracak bir tarayıcı geliştirmenin "
+"yanında üçüncü taraf geliştiricilerin uygulamalarını Tor ile "
"bütünleştirmesini kolaylaştırmak gibi iddialı projelere girişebileceğiz. ."
#: tmp/cache_locale/ca/ca1cd152d40544030a642d8d074e6afb769c3bf80a1b2b61c380f1466e3a03a4.php:61
@@ -462,7 +461,7 @@ msgstr "Toplam Bağış Tutarı"
#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:159
msgid "Total Raised with Mozilla's Match"
-msgstr "Mozilla Kampanyası ile Toplam Tutar"
+msgstr "Mozilla Bağış Katlama Kampanyası ile Toplam Tutar"
#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:170
#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:176
@@ -744,7 +743,7 @@ msgstr ""
#: tmp/cache_locale/c7/c763c19bb6abb9330294c550c8241bb3874e3b4e17fb6e7b15db26c60df8d5fe.php:651
#: tmp/cache_locale/9f/9f870858aaf6c5a7c94ea6a959618fbe485cbfd16174993d34a8e370a4567526.php:84
msgid "Mozilla will match your gift and double your impact."
-msgstr "Mozilla eşit miktarda bir bağış yapacak ve hediyeniz katlanacak."
+msgstr "Mozilla eşit miktarda bir bağış yapacak ve bağışınız katlanacak."
#: tmp/cache_locale/af/afda2fbd22ed389453e63ca9acc074a25ce820b5bc97120edfd975cf8f46634a.php:61
msgid "Thank you for your support of the Tor Project."
@@ -1772,7 +1771,7 @@ msgstr "Evet"
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:496
msgid "Does Tor Project accept matching donations?"
-msgstr "Tor Project eşleşen bağışları kabul eder mi? "
+msgstr "Tor Projesi bağış katlama kampanyası yapıyor mu? "
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:500
msgid ""
@@ -1780,9 +1779,9 @@ msgid ""
"Verizon, Red Hat, many universities, and others-- will match donations made "
"by their employees."
msgstr ""
-"Evet! Çoğu şirket Google, Microsoft, eBay, PayPal, Apple, Verizon, Red Hat, "
-"çoğu üniversite ve diğerleri gibi çalışanları tarafından yapılan bağışları "
-"karşılaştıracaktır."
+"Evet! Google, Microsoft, eBay, PayPal, Apple, Verizon, Red Hat gibi "
+"şirketler, pek çok üniversite ve diğer kuruluşlar çalışanlarının yaptıkları "
+"bağış kadar bağış yaparak toplam bağış tutarını katlıyor."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:502
msgid ""
@@ -1791,39 +1790,38 @@ msgid ""
" <a class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.matchinggifts.com/rit/\">https://www.matchinggifts.com/rit/</a>."
msgstr ""
-"Sizin şirketinizin bağışları karşılaştırdığını bulmanın en hızlı yolu "
-"genellikle sizin HR departmanınızı kontrol ederek olur ya da siz şirket "
-"adınızı <a class=\"hyperlinks links\" target=\"_blank\" "
+"Kuruluşunuzun bağış katlama kampanyası yapıp yapmadığını genellikle İK "
+"bölümünden öğrenebilirsiniz. Ayrıca kuruluşunuzun adının <a "
+"class=\"hyperlinks links\" target=\"_blank\" "
"href=\"https://www.matchinggifts.com/rit/\"> "
-"https://www.matchinggifts.com/rit/</a>'te arayabilirsiniz. "
+"https://www.matchinggifts.com/rit/</a>sayfasında yer alıp almadığına da "
+"bakabilirsiniz. "
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:504
msgid ""
"If your company isn't currently set up to match donations to the Tor "
"Project, we would be happy to help with the paperwork."
msgstr ""
-"Eğer şirketiniz, şu an için Tor Projesine eş bağışını düzenlemediyse, kağıt "
-"işlerinde yardım etmekten mutluluk duyarız."
+"Kuruluşunuz şu anda Tor Projesi için bir bağış katlama kampanyası "
+"yapmıyorsa, gerekli kağıt işlerine yardımcı olmaktan mutluluk duyarız."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:506
msgid ""
"If you want help figuring out the process, write us at <span "
"class=\"email\">giving(at)torproject.org</a>."
msgstr ""
-"Süreçle ilgili yardıma ihtiyacınız varsa bize <span "
+"Süreçle ilgili yardıma gerek duyarsanız bize <span "
"class=\"email\">giving(at)torproject.org</a> adresinden ulaşabilirsiniz."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:512
msgid "Can I become a Tor Project member?"
-msgstr "Tor Projesi'nin bir parçası olabilir miyim?"
+msgstr "Tor Projesine katılabilir miyim?"
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:516
msgid ""
"Right now, we don't have a membership program, but we may set one up in the "
"future."
-msgstr ""
-"Şimdilik herhangi bir üyelik programımız yok, ama ilerleyen zamanlarda bir "
-"tane hazırlama ihtimalimiz var."
+msgstr "Şimdilik herhangi bir üyelik programımız yok. Ancak ileride olabilir."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:518
msgid ""
@@ -1832,10 +1830,10 @@ msgid ""
"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">this is a "
"good place to start</a>."
msgstr ""
-"Tor Projesi'yle ilgilenmek istiyorsanız, <a class=\"hyperlinks links\" "
+"Tor Projesine katkıda bulunmak istiyorsanız, <a class=\"hyperlinks links\" "
"target=\"_blank\" "
-"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">burası "
-"başlamak için iyi bir yerdir</a>."
+"href=\"https://www.torproject.org/getinvolved/volunteer.html.en\">buradan "
+"başlayabilirsiniz</a>."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:524
msgid "How can I get a Tor t-shirt or stickers?"
@@ -1951,8 +1949,8 @@ msgid ""
"Your company could match donations made by its employees to the Tor Project"
"--that would be wonderful."
msgstr ""
-"Şirketiniz, Tor Projesine çalışanlarınızın yaptığı bağışlara denk bir bağış "
-"yapabilir, bu mükemmel olur."
+"Kuruluşunuz Tor Projesine çalışanlarının yaptığı kadar bir bağış yaparsa bu "
+"harika olur."
#: tmp/cache_locale/0e/0e65c68f2900f432bc062864e7bafc989d6286e272f5e98882a99f52ea4c5c89.php:600
msgid ""
@@ -2042,7 +2040,9 @@ msgstr ""
#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:22
msgid "See if your employer offers employee gift matching"
-msgstr "İşvereniniz çalışanlara hediye katlama olanağı sunar mı"
+msgstr ""
+"Kuruluşunuzun çalışanlarına bağış katlama kampanyası yapıp yapmadığını "
+"öğrenin"
#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:52
msgid "Company"
@@ -2050,7 +2050,7 @@ msgstr "Kuruluş"
#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:60
msgid "Matching Conditions"
-msgstr "Katlama Koşulları"
+msgstr "Bağış Katlama Kampanyası Koşulları"
#: tmp/cache_locale/08/08a9b06344a88c9ea01db4cdf9711c9cee305183a512ae0e8b7381dae8c6d798.php:68
msgid "Contact Information"
1
0

[translation/support-portal] Update translations for support-portal
by translation@torproject.org 26 Mar '19
by translation@torproject.org 26 Mar '19
26 Mar '19
commit dcde0607541b2c0b4ae3fcd1321e8a831a6d4d8e
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 06:20:28 2019 +0000
Update translations for support-portal
---
contents+ar.po | 7 ++++---
contents+tr.po | 36 ++++++++++++++++++++++++++++--------
2 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/contents+ar.po b/contents+ar.po
index cf58856cf..e2774697c 100644
--- a/contents+ar.po
+++ b/contents+ar.po
@@ -4,6 +4,7 @@
# erinm, 2019
# ButterflyOfFire ButterflyOfFire, 2019
# Emma Peel, 2019
+# Ahmed A. <6622227a(a)gmail.com>, 2019
#
msgid ""
msgstr ""
@@ -11,7 +12,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-19 08:55+CET\n"
"PO-Revision-Date: 2018-10-02 22:41+0000\n"
-"Last-Translator: Emma Peel, 2019\n"
+"Last-Translator: Ahmed A. <6622227a(a)gmail.com>, 2019\n"
"Language-Team: Arabic (https://www.transifex.com/otf/teams/1519/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -5069,7 +5070,7 @@ msgstr "التوثيق"
#: https//support.torproject.org/misc/menu/
#: (content/misc/menu/contents+en.lrquestion.description)
msgid "Press"
-msgstr ""
+msgstr "صحافة"
#: https//support.torproject.org/misc/menu/
#: (content/misc/menu/contents+en.lrquestion.description)
@@ -5079,7 +5080,7 @@ msgstr "مدونة"
#: https//support.torproject.org/misc/menu/
#: (content/misc/menu/contents+en.lrquestion.description)
msgid "Newsletter"
-msgstr ""
+msgstr "نشرة إعلامية"
#: https//support.torproject.org/misc/menu/
#: (content/misc/menu/contents+en.lrquestion.description)
diff --git a/contents+tr.po b/contents+tr.po
index 1871cdc6d..113fdd6d1 100644
--- a/contents+tr.po
+++ b/contents+tr.po
@@ -4740,6 +4740,9 @@ msgid ""
" for accessing and using the Internet. When using [Tor Browser](#tor-"
"browser), your ISP cannot see what websites you're visiting."
msgstr ""
+"İnternet hizmeti sağlayıcısı (ISP), İnternet erişiminizi sağlayan bir "
+"kuruluştur. [Tor Browser] (#tor-browser) kullanırken, İnternet hizmeti "
+"sağlayıcınız ziyaret ettiğiniz web sitelerinin neler olduğunu göremez."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4754,6 +4757,10 @@ msgid ""
" participating in a computer network that uses the Internet Protocol for "
"communication."
msgstr ""
+"Bir İnternet iletişim kuralı adresi (Internet Protocol adresi), iletişim "
+"için İnternet iletişim kuralını kullanan bir bilgisayar ağına katılan her "
+"aygıta (bilgisayar, tablet, yazıcı gibi) atanan sayısal (ya da IPv6 olması "
+"durumunda alfa sayısal) bir etikettir."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4761,6 +4768,8 @@ msgid ""
"IP addresses are the location address of the device, similar to the "
"addresses of physical locations."
msgstr ""
+"IP adresleri, normal ev ve iş yeri adreslerine benzer şekilde aygıtın "
+"konumunu belirtir."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4768,6 +4777,8 @@ msgid ""
"[Tor Browser](#tor-browser) obscures your location by making it look like "
"your [traffic](#traffic) is coming from an IP address that is not your own."
msgstr ""
+"[Tor Browser](#tor-browser), [trafiğinizi](#traffic) farklı bir IP "
+"adresinden geliyormuş gibi göstererek gerçek konumunuzu gizler."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4790,6 +4801,13 @@ msgid ""
"Browser](#tor-browser) can be used to manage Javascript on different "
"websites."
msgstr ""
+"JavaScript, web sitelerinde görüntü, ses, canlandırma ve zamana göre değişen"
+" durumlar gibi etkileşimli ögeler sunması için kullanılan bir programlama "
+"dilidir. Maalesef, JavaScript ayrıca [web tarayıcı](#web-browser) "
+"güvenliğine yönelik saldırılara da kapı açtığından kimliğinizin açığa "
+"çıkmasına neden olabilir. [Tor Browser](#tor-browser) üzerine yüklenmiş "
+"gelen [NoScript](#noscript) [eklentisi](#add-on-extension-orplugin) her web "
+"sitesi için Javascript kullanılıp kullanılmayacağını seçebilmenizi sağlar."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4812,6 +4830,8 @@ msgid ""
"\"little-t tor\" is one way of referring to tor the network daemon, as "
"opposed to Tor Browser or Tor Project."
msgstr ""
+"\"little-t tor\" Tor Browser ya da Tor Projesi yerine tor ağ arka plan "
+"işlemini ifade etmek için kullanılır."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -5882,8 +5902,8 @@ msgid ""
"The same protections that keep bad people from breaking Tor's anonymity also"
" prevent us from tracking users."
msgstr ""
-"Kötü niyetli kişilerin Tor anonimliğini bozmasını engelleyen koruma "
-"yöntemleri bizim Tor kullanıcılarını izlememizi de engeller."
+"Tor üzerindeki anonim kimliğinizi kötü niyetli kişilere karşı koruyan "
+"önlemler bizim Tor kullanıcılarını izlememizi de engeller."
#: https//support.torproject.org/misc/does-tor-project-offer-hosting/
#: (content/misc/misc-10/contents+en.lrquestion.title)
@@ -5906,8 +5926,8 @@ msgid ""
"Right now the path length is hard-coded at 3 plus the number of nodes in "
"your path that are sensitive."
msgstr ""
-"Şu anda yol uzunluğu donanımsal olarak 3 artı yolunuzdaki duyarlı düğüm "
-"sayısı ile sınırlandırılmıştır."
+"Şu anda yol uzunluğu, sabit olarak 3 düğüm, artı yolunuzdaki duyarlı düğüm "
+"sayısı olarak belirlenmiştir."
#: https//support.torproject.org/misc/change-the-number-of-hops-tor-uses/
#: (content/misc/misc-11/contents+en.lrquestion.description)
@@ -5915,8 +5935,8 @@ msgid ""
"That is, in normal cases it's 3, but for example if you're accessing an "
"onion service or a \".exit\" address it could be more."
msgstr ""
-"Normal durumlarda 3 olur. Ancak bir onion hizmetine ya da \".exit\" adresine"
-" erişiyorsanız daha uzun olabilir."
+"Normal durumlarda 3 düğüm kullanılır. Ancak bir onion hizmetine ya da "
+"\".exit\" adresine erişiyorsanız daha uzun olabilir."
#: https//support.torproject.org/misc/change-the-number-of-hops-tor-uses/
#: (content/misc/misc-11/contents+en.lrquestion.description)
@@ -5925,8 +5945,8 @@ msgid ""
"increases load on the network without (as far as we can tell) providing any "
"more security."
msgstr ""
-"Güvenliği arttırmadığı halde ağ üzerindeki yükü arttırdığı için "
-"(bilebildiğimiz kadarıyla) bundan uzun yolların kullanılmasını önermiyoruz. "
+"Güvenliği arttırmadığı halde (bilebildiğimiz kadarıyla) ağ yükünü arttırdığı"
+" için bundan uzun yolların kullanılmasını önermiyoruz. "
#: https//support.torproject.org/misc/change-the-number-of-hops-tor-uses/
#: (content/misc/misc-11/contents+en.lrquestion.description)
1
0

26 Mar '19
commit 1f6855017d53510dc7c3b988fcde574df60d8bc5
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 06:20:07 2019 +0000
Update translations for tpo-web
---
contents+ar.po | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/contents+ar.po b/contents+ar.po
index 75a28716e..e5b02f477 100644
--- a/contents+ar.po
+++ b/contents+ar.po
@@ -5,6 +5,7 @@
# ButterflyOfFire ButterflyOfFire, 2019
# erinm, 2019
# Emma Peel, 2019
+# Ahmed A. <6622227a(a)gmail.com>, 2019
#
msgid ""
msgstr ""
@@ -12,7 +13,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-19 18:48+CET\n"
"PO-Revision-Date: 2019-03-09 10:41+0000\n"
-"Last-Translator: Emma Peel, 2019\n"
+"Last-Translator: Ahmed A. <6622227a(a)gmail.com>, 2019\n"
"Language-Team: Arabic (https://www.transifex.com/otf/teams/1519/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -109,7 +110,7 @@ msgstr "التوثيق"
#: https//www.torproject.org/menu/ (content/menu/contents+en.lrpage.body)
msgid "Press"
-msgstr ""
+msgstr "صحافة"
#: https//www.torproject.org/menu/ (content/menu/contents+en.lrpage.body)
msgid "Blog"
@@ -117,7 +118,7 @@ msgstr "مدونة"
#: https//www.torproject.org/menu/ (content/menu/contents+en.lrpage.body)
msgid "Newsletter"
-msgstr ""
+msgstr "نشرة إعلامية"
#: https//www.torproject.org/menu/ (content/menu/contents+en.lrpage.body)
msgid "Support"
@@ -2493,7 +2494,7 @@ msgstr ""
#: templates/navbar.html:14
msgid "Menu"
-msgstr ""
+msgstr "القائمة"
#: templates/people.html:2
msgid "Board of Directors"
1
0

[translation/tbmanual-contentspot] Update translations for tbmanual-contentspot
by translation@torproject.org 26 Mar '19
by translation@torproject.org 26 Mar '19
26 Mar '19
commit 7b9c62e4817ef4f2fa32fff7c49de01a7ae76d11
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 06:17:37 2019 +0000
Update translations for tbmanual-contentspot
---
contents+ar.po | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/contents+ar.po b/contents+ar.po
index bae135b65..c921460a8 100644
--- a/contents+ar.po
+++ b/contents+ar.po
@@ -3,6 +3,7 @@
# ButterflyOfFire ButterflyOfFire, 2018
# erinm, 2019
# Emma Peel, 2019
+# Ahmed A. <6622227a(a)gmail.com>, 2019
#
msgid ""
msgstr ""
@@ -10,7 +11,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-03-22 10:16+CET\n"
"PO-Revision-Date: 2018-11-14 12:31+0000\n"
-"Last-Translator: Emma Peel, 2019\n"
+"Last-Translator: Ahmed A. <6622227a(a)gmail.com>, 2019\n"
"Language-Team: Arabic (https://www.transifex.com/otf/teams/1519/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -26,7 +27,7 @@ msgstr "دليل استخدام متصفّح تور"
#: https//tb-manual.torproject.org/en-US/menu/
#: (content/menu/contents+en-US.lrtopic.title)
msgid "Menu"
-msgstr ""
+msgstr "القائمة"
#: https//tb-manual.torproject.org/en-US/menu/
#: (content/menu/contents+en-US.lrtopic.body)
@@ -41,7 +42,7 @@ msgstr "التوثيق"
#: https//tb-manual.torproject.org/en-US/menu/
#: (content/menu/contents+en-US.lrtopic.body)
msgid "Press"
-msgstr ""
+msgstr "صحافة"
#: https//tb-manual.torproject.org/en-US/menu/
#: (content/menu/contents+en-US.lrtopic.body)
@@ -51,7 +52,7 @@ msgstr "مدونة"
#: https//tb-manual.torproject.org/en-US/menu/
#: (content/menu/contents+en-US.lrtopic.body)
msgid "Newsletter"
-msgstr ""
+msgstr "نشرة إعلامية"
#: https//tb-manual.torproject.org/en-US/menu/
#: (content/menu/contents+en-US.lrtopic.body)
@@ -788,7 +789,7 @@ msgstr "<img class=\"col-md-6\" src=\"../../static/images/bridges.png\">"
#: https//tb-manual.torproject.org/en-US/circumvention/
#: (content/circumvention/contents+en-US.lrtopic.body)
msgid "Click 'OK' to save your settings."
-msgstr ""
+msgstr "إضغط \"OK\" لحفظ الاعدادات."
#: https//tb-manual.torproject.org/en-US/circumvention/
#: (content/circumvention/contents+en-US.lrtopic.body)
@@ -1003,6 +1004,8 @@ msgid ""
"Tor Browser features “New Identity” and “New Tor Circuit for this Site” "
"options, located in the main menu (hamburger menu)."
msgstr ""
+"خواص متصفح تور \"هوية جديدة\" و \"دائرة جديدة إلي الموقع\"، متواجدة في "
+"القائمة الرئيسية (قائمة هامبرجر)."
#: https//tb-manual.torproject.org/en-US/managing-identities/
#: (content/managing-identities/contents+en-US.lrtopic.body)
1
0

[translation/support-portal] Update translations for support-portal
by translation@torproject.org 26 Mar '19
by translation@torproject.org 26 Mar '19
26 Mar '19
commit c65694ba79c8b43d6fa75e6008d34d7a4ff6bd37
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 04:20:34 2019 +0000
Update translations for support-portal
---
contents+tr.po | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/contents+tr.po b/contents+tr.po
index 09e30d398..1871cdc6d 100644
--- a/contents+tr.po
+++ b/contents+tr.po
@@ -4648,6 +4648,8 @@ msgid ""
"Former name for \"[onion services](#onion-services)\", sometimes still in "
"use in [Tor](#tor-/-tor-network/-core-tor) documentation or communication."
msgstr ""
+"\"[Onion hizmetlerinin](#onion-services)\" eski adı. Bazen [Tor](#tor-/-tor-"
+"network/-core-tor) belgelerinde ya da iletişiminde karşılaşabilirsiniz."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4660,6 +4662,9 @@ msgid ""
"In [Tor](#tor-/-tor-network/-core-tor) terms, a \"hop\" refers to "
"[traffic](#traffic) moving between [relay](#relay) in a [circuit](#circuit)."
msgstr ""
+"[Tor](#tor-/-tor-network/-core-tor) ortamında bir \"durak\" "
+"[trafiğin](#traffic) bir [devredeki](#circuit) bir [aktarıcıdan](#relay) "
+"geçmesini ifade eder."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4674,6 +4679,10 @@ msgid ""
"only web pages, it is now relied upon to deliver many forms of data and "
"communication."
msgstr ""
+"[Hypertext Transfer Protocol(HTTP)](#http) bir ağdaki aygıtlar arasında veri"
+" ve dosyaların aktarılması için kullanılan bir iletişim kuralı kanalıdır. "
+"Yalnız web sayfalarını aktarmak için tasarlanmış olsa da farklı pek çok "
+"şekilde verileri aktarmak ve iletişim kurmak amacıyla da kullanılmaktadır."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4687,6 +4696,9 @@ msgid ""
"of the HTTP channel used to transfer files and data between devices on a "
"network."
msgstr ""
+"Güvenli Hypertext Transfer Protocol, bir ağdaki aygıtlar arasında veri ve "
+"dosyaların aktarılması için kullanılan HTTP iletişim kuralı kanalının "
+"[şifrelenmiş](#encryption) sürümüdür."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4700,11 +4712,16 @@ msgid ""
"](#add-on-extension-or-plugin) that makes [HTTPS](#https) the default on "
"websites that have set up HTTPS but have not made it the default."
msgstr ""
+"HTTPS Everywhere, [Firefox](#firefox), Chrome ve Opera üzerinde çalışan bir "
+"[tarayıcı eklentisidir](#add-on-extension-or-plugin). HTTPS bağlantısını "
+"destekleyen ancak varsayılan olarak kullanmayan web sitelerine varsayılan "
+"olarak [HTTPS](#https) ile bağlanılmasını sağlar."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
msgid "HTTPS Everywhere is installed in [Tor Browser](#tor-browser)."
msgstr ""
+"HTTPS Everywhere [Tor Browser](#tor-browser) üzerine kurulmuş olarak gelir."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
1
0

[translation/support-portal] Update translations for support-portal
by translation@torproject.org 26 Mar '19
by translation@torproject.org 26 Mar '19
26 Mar '19
commit 18d9ae1cbad63cef9609267959efff57bd2db743
Author: Translation commit bot <translation(a)torproject.org>
Date: Tue Mar 26 03:50:36 2019 +0000
Update translations for support-portal
---
contents+tr.po | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/contents+tr.po b/contents+tr.po
index 7fb8b8467..09e30d398 100644
--- a/contents+tr.po
+++ b/contents+tr.po
@@ -4516,6 +4516,15 @@ msgid ""
"connections. You can reconfigure or disable your firewall and restart Tor to"
" test this."
msgstr ""
+"Güvenlik duvarı, ağdan gelen ve giden [trafiği](#traffic) izleyen ve "
+"denetleyen bir ağ güvenlik sistemidir. Trafiği önceden belirlenmiş kurallara"
+" göre süzer. Bir güvenlik duvarı genellikle güvenilen ve korunan bir iç ağ "
+"ile bir dış ağ arasında bir engel oluşturur. Ancak [sansür](#network-"
+"cencorship) uygulamak amacıyla içerikleri süzmek için de kullanılabilir. "
+"Bazen insanlar güvenlik duvarları Tor bağlantılarını engellediği için "
+"[Tor](#tor-/-tor-network/-core-tor) bağlantısı kurmakta sorun yaşarlar. Bu "
+"sorunu çözmek için güvenlik duvarınızı yeniden yapılandırabilir ya da devre "
+"dışı bırakabilirsiniz."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4531,6 +4540,12 @@ msgid ""
"services that use Flash also offer an HTML5 alternative, which should work "
"in the Tor Browser."
msgstr ""
+"Flash Player, İnternet [uygulamalarında](#app) ses ve görüntü içeriğini "
+"oynatmak için kullanılan bir [tarayıcı eklentisidir](#add-on-extension-or-"
+"plugin). Güvenli olmadığından [Tor Browser](#tor-browser) kullanırken Flash "
+"eklentisini asla etkinleştirmemelisiniz. Flash kullanan birçok hizmet, aynı "
+"içeriğin Tor Tarayıcı ile görüntülenebilmesini sağlayan bir HTML5 "
+"alternatifi sunar."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4543,6 +4558,9 @@ msgid ""
"FTE (format-transforming encryption) is a pluggable transport that disguises"
" [Tor traffic](#traffic) as ordinary web (HTTP) traffic."
msgstr ""
+"FTE (format-transforming encryption, biçim dönüştürme şifrelemesi), [Tor "
+"trafiğinin](#traffic) sıradan web trafiği (HTTP) gibi görünmesini sağlayan "
+"bir değiştirilebilir taşıyıcıdır."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4561,6 +4579,9 @@ msgid ""
"Twitter) with links to the latest version of [Tor Browser](#tor-browser), "
"hosted at a variety of locations, such as Dropbox, Google Drive and Github."
msgstr ""
+"Gönderilen iletilere (E-posta, XMPP, Twitter), Dropbox, Google Drive ve "
+"Github gibi çeşitli yerlere yüklenmiş son [Tor Browser](#tor-browser) "
+"sürümünün bağlantıları ile otomatik olarak yanıt veren bir hizmettir."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4573,6 +4594,8 @@ msgid ""
"The Tor Project participates in the Google Summer of Code, which is a summer"
" program for university students."
msgstr ""
+"Tor projesi üniversite öğrencileri için hazırlanmış bir yaz programı olan "
+"Google Summur of Code etkinliğine katılır."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4586,6 +4609,9 @@ msgid ""
"[bridge](#bridge). When using a bridge, the bridge takes the place of the "
"guard."
msgstr ""
+"Bir [köprü](#bridge) kullanımıyorsa [Tor devresindeki](#circuit) ilk "
+"[aktarıcı](#relay). Bir köprü kullanıldığında köprü aktarıcısı koruyucunun "
+"yerini alır."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
@@ -4605,6 +4631,11 @@ msgid ""
" which means the value is easy to calculate in one direction but infeasible "
"to invert. Hash values serve to verify the integrity of data."
msgstr ""
+"Şifreleme karma değeri, verileri sabit boyutlu bir bit dizgesi ile "
+"eşleştiren matematiksel bir algoritmanın sonucudur. Tek yönlü bir işlev "
+"olarak tasarlanmıştır; yani değer bir yöne doğru kolayca hesaplanır ancak "
+"tersine çevrilmesi anlamlı değildir. Karma değerleri, verilerin bütünlüğünün"
+" bozulmamış olduğunu doğrulamak için kullanılır."
#: https//support.torproject.org/misc/tor-glossary/
#: (content/misc/glossary/contents+en.lrquestion.description)
1
0