1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "sync/internal_api/syncapi_internal.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "sync/protocol/attachments.pb.h"
9 #include "sync/protocol/password_specifics.pb.h"
10 #include "sync/protocol/sync.pb.h"
11 #include "sync/util/cryptographer.h"
17 bool EndsWithSpace(const std::string
& string
) {
18 return !string
.empty() && *string
.rbegin() == ' ';
23 sync_pb::PasswordSpecificsData
* DecryptPasswordSpecifics(
24 const sync_pb::EntitySpecifics
& specifics
, Cryptographer
* crypto
) {
25 if (!specifics
.has_password())
27 const sync_pb::PasswordSpecifics
& password_specifics
= specifics
.password();
28 if (!password_specifics
.has_encrypted())
30 const sync_pb::EncryptedData
& encrypted
= password_specifics
.encrypted();
31 scoped_ptr
<sync_pb::PasswordSpecificsData
> data(
32 new sync_pb::PasswordSpecificsData
);
33 if (!crypto
->Decrypt(encrypted
, data
.get()))
35 return data
.release();
38 // The list of names which are reserved for use by the server.
39 static const char* kForbiddenServerNames
[] = { "", ".", ".." };
41 // When taking a name from the syncapi, append a space if it matches the
42 // pattern of a server-illegal name followed by zero or more spaces.
43 void SyncAPINameToServerName(const std::string
& syncer_name
,
46 if (IsNameServerIllegalAfterTrimming(*out
))
50 // In the reverse direction, if a server name matches the pattern of a
51 // server-illegal name followed by one or more spaces, remove the trailing
53 void ServerNameToSyncAPIName(const std::string
& server_name
,
56 int length_to_copy
= server_name
.length();
57 if (IsNameServerIllegalAfterTrimming(server_name
) &&
58 EndsWithSpace(server_name
)) {
61 *out
= server_name
.substr(0, length_to_copy
);
64 // Checks whether |name| is a server-illegal name followed by zero or more space
65 // characters. The three server-illegal names are the empty string, dot, and
66 // dot-dot. Very long names (>255 bytes in UTF-8 Normalization Form C) are
67 // also illegal, but are not considered here.
68 bool IsNameServerIllegalAfterTrimming(const std::string
& name
) {
69 size_t untrimmed_count
= name
.find_last_not_of(' ') + 1;
70 for (size_t i
= 0; i
< arraysize(kForbiddenServerNames
); ++i
) {
71 if (name
.compare(0, untrimmed_count
, kForbiddenServerNames
[i
]) == 0)
77 // Compare the values of two EntitySpecifics, accounting for encryption.
78 bool AreSpecificsEqual(const Cryptographer
* cryptographer
,
79 const sync_pb::EntitySpecifics
& left
,
80 const sync_pb::EntitySpecifics
& right
) {
81 // Note that we can't compare encrypted strings directly as they are seeded
82 // with a random value.
83 std::string left_plaintext
, right_plaintext
;
84 if (left
.has_encrypted()) {
85 if (!cryptographer
->CanDecrypt(left
.encrypted())) {
86 NOTREACHED() << "Attempting to compare undecryptable data.";
89 left_plaintext
= cryptographer
->DecryptToString(left
.encrypted());
91 left_plaintext
= left
.SerializeAsString();
93 if (right
.has_encrypted()) {
94 if (!cryptographer
->CanDecrypt(right
.encrypted())) {
95 NOTREACHED() << "Attempting to compare undecryptable data.";
98 right_plaintext
= cryptographer
->DecryptToString(right
.encrypted());
100 right_plaintext
= right
.SerializeAsString();
102 if (left_plaintext
== right_plaintext
) {
108 bool AreAttachmentMetadataEqual(const sync_pb::AttachmentMetadata
& left
,
109 const sync_pb::AttachmentMetadata
& right
) {
110 if (left
.SerializeAsString() == right
.SerializeAsString()) {
116 } // namespace syncer