1 /**
2  * (c) 2019 by Mega Limited, Wellsford, New Zealand
3  *
4  * This file is part of the MEGA SDK - Client Access Engine.
5  *
6  * Applications using the MEGA API must present a valid application key
7  * and comply with the the rules set forth in the Terms of Service.
8  *
9  * The MEGA SDK is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * @copyright Simplified (2-clause) BSD License.
14  *
15  * You should have received a copy of the license along with this
16  * program.
17  */
18 
19 #include <gtest/gtest.h>
20 
21 #include <mega/megaclient.h>
22 #include <mega/megaapp.h>
23 #include <mega/transfer.h>
24 
25 #include "DefaultedFileSystemAccess.h"
26 #include "utils.h"
27 #include "mega.h"
28 
29 namespace
30 {
31 
checkTransfers(const mega::Transfer & exp,const mega::Transfer & act)32 void checkTransfers(const mega::Transfer& exp, const mega::Transfer& act)
33 {
34     ASSERT_EQ(exp.type, act.type);
35     ASSERT_EQ(exp.localfilename, act.localfilename);
36     ASSERT_TRUE(std::equal(exp.filekey, exp.filekey + mega::FILENODEKEYLENGTH, act.filekey));
37     ASSERT_EQ(exp.ctriv, act.ctriv);
38     ASSERT_EQ(exp.metamac, act.metamac);
39     ASSERT_TRUE(std::equal(exp.transferkey.data(),
40                            exp.transferkey.data() + mega::SymmCipher::KEYLENGTH,
41                            act.transferkey.data()));
42     ASSERT_EQ(exp.lastaccesstime, act.lastaccesstime);
43     ASSERT_TRUE(std::equal(exp.ultoken, exp.ultoken + mega::NewNode::UPLOADTOKENLEN, act.ultoken));
44     ASSERT_EQ(exp.tempurls, act.tempurls);
45     ASSERT_EQ(exp.state, act.state);
46     ASSERT_EQ(exp.priority, act.priority);
47 }
48 
49 }
50 
TEST(Transfer,serialize_unserialize)51 TEST(Transfer, serialize_unserialize)
52 {
53     mega::MegaApp app;
54     ::mega::FSACCESS_CLASS fsaccess;
55     auto client = mt::makeClient(app, fsaccess);
56 
57     mega::Transfer tf{client.get(), mega::GET};
58     std::string lfn = "foo";
59     tf.localfilename = ::mega::LocalPath::fromPath(lfn, fsaccess);
60     std::fill(tf.filekey, tf.filekey + mega::FILENODEKEYLENGTH, 'X');
61     tf.ctriv = 1;
62     tf.metamac = 2;
63     std::fill(tf.transferkey.data(),
64               tf.transferkey.data() + mega::SymmCipher::KEYLENGTH,
65               'Y');
66     tf.lastaccesstime = 3;
67     tf.ultoken = new mega::byte[mega::NewNode::UPLOADTOKENLEN];
68     std::fill(tf.ultoken, tf.ultoken + mega::NewNode::UPLOADTOKENLEN, 'Z');
69     tf.tempurls = {
70         "http://bar1.com",
71         "http://bar2.com",
72         "http://bar3.com",
73         "http://bar4.com",
74         "http://bar5.com",
75         "http://bar6.com",
76     };
77     tf.state = mega::TRANSFERSTATE_PAUSED;
78     tf.priority = 4;
79 
80     std::string d;
81     ASSERT_TRUE(tf.serialize(&d));
82 
83     mega::transfer_map tfMap;
84     auto newTf = std::unique_ptr<mega::Transfer>{mega::Transfer::unserialize(client.get(), &d, &tfMap)};
85     checkTransfers(tf, *newTf);
86 }
87 
88 #ifndef WIN32
TEST(Transfer,unserialize_32bit)89 TEST(Transfer, unserialize_32bit)
90 {
91     mega::MegaApp app;
92     ::mega::FSACCESS_CLASS fsaccess;
93     auto client = mt::makeClient(app, fsaccess);
94 
95     mega::Transfer tf{client.get(), mega::GET};
96     std::string lfn = "foo";
97     tf.localfilename = ::mega::LocalPath::fromPath(lfn, fsaccess);
98     std::fill(tf.filekey, tf.filekey + mega::FILENODEKEYLENGTH, 'X');
99     tf.ctriv = 1;
100     tf.metamac = 2;
101     std::fill(tf.transferkey.data(),
102               tf.transferkey.data() + mega::SymmCipher::KEYLENGTH,
103               'Y');
104     tf.lastaccesstime = 3;
105     tf.ultoken = new mega::byte[mega::NewNode::UPLOADTOKENLEN];
106     std::fill(tf.ultoken, tf.ultoken + mega::NewNode::UPLOADTOKENLEN, 'Z');
107     tf.tempurls = {
108         "http://bar1.com",
109         "http://bar2.com",
110         "http://bar3.com",
111         "http://bar4.com",
112         "http://bar5.com",
113         "http://bar6.com",
114     };
115     tf.state = mega::TRANSFERSTATE_PAUSED;
116     tf.priority = 4;
117 
118     // This is the result of serialization on 32bit Windows
119     const std::array<unsigned char, 293> rawData = {
120         0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x66, 0x6f, 0x6f, 0x58, 0x58, 0x58,
121         0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
122         0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
123         0x58, 0x58, 0x58, 0x58, 0x58, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124         0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x59, 0x59,
125         0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59,
126         0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129         0xff, 0xff, 0xff,
130         0xff, 0xff, 0xff,
131         0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
132         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
134         0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
135         0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
136         0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
137         0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5f, 0x00, 0x68, 0x74, 0x74, 0x70,
138         0x3a, 0x2f, 0x2f, 0x62, 0x61, 0x72, 0x31, 0x2e, 0x63, 0x6f, 0x6d, 0x00,
139         0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x62, 0x61, 0x72, 0x32, 0x2e,
140         0x63, 0x6f, 0x6d, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x62,
141         0x61, 0x72, 0x33, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x68, 0x74, 0x74, 0x70,
142         0x3a, 0x2f, 0x2f, 0x62, 0x61, 0x72, 0x34, 0x2e, 0x63, 0x6f, 0x6d, 0x00,
143         0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x62, 0x61, 0x72, 0x35, 0x2e,
144         0x63, 0x6f, 0x6d, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x62,
145         0x61, 0x72, 0x36, 0x2e, 0x63, 0x6f, 0x6d, 0x03, 0x04, 0x00, 0x00, 0x00,
146         0x00, 0x00, 0x00, 0x00, 0x00
147     };
148     std::string d(reinterpret_cast<const char*>(rawData.data()), rawData.size());
149 
150     mega::transfer_map tfMap;
151     auto newTf = std::unique_ptr<mega::Transfer>{mega::Transfer::unserialize(client.get(), &d, &tfMap)};
152     checkTransfers(tf, *newTf);
153 }
154 #endif
155