summaryrefslogtreecommitdiffstats
path: root/browser/components/migration/tests/unit/test_IE_cookies.js
blob: bb003ad5a563e0b45f556d8117411348d51bf2e1 (plain)
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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"use strict";

ChromeUtils.defineModuleGetter(
  this,
  "ctypes",
  "resource://gre/modules/ctypes.jsm"
);

add_task(async function() {
  let migrator = await MigrationUtils.getMigrator("ie");
  // Sanity check for the source.
  Assert.ok(await migrator.isSourceAvailable());

  // Windows versions newer than 1709 don't store cookies as files anymore,
  // thus our migrators don't import anything and this test is pointless.
  // In these versions the CookD folder contains a deprecated.cookie file.
  let deprecatedCookie = Services.dirsvc.get("CookD", Ci.nsIFile);
  deprecatedCookie.append("deprecated.cookie");
  if (deprecatedCookie.exists()) {
    return;
  }

  const BOOL = ctypes.bool;
  const LPCTSTR = ctypes.char16_t.ptr;
  const DWORD = ctypes.uint32_t;
  const LPDWORD = DWORD.ptr;

  let wininet = ctypes.open("Wininet");

  /*
  BOOL InternetSetCookieW(
    _In_  LPCTSTR lpszUrl,
    _In_  LPCTSTR lpszCookieName,
    _In_  LPCTSTR lpszCookieData
  );
  */
  // NOTE: Even though MSDN documentation does not indicate a calling convention,
  // InternetSetCookieW is declared in SDK headers as __stdcall but is exported
  // from wininet.dll without name mangling, so it is effectively winapi_abi
  let setIECookie = wininet.declare(
    "InternetSetCookieW",
    ctypes.winapi_abi,
    BOOL,
    LPCTSTR,
    LPCTSTR,
    LPCTSTR
  );

  /*
  BOOL InternetGetCookieW(
    _In_    LPCTSTR lpszUrl,
    _In_    LPCTSTR lpszCookieName,
    _Out_   LPCTSTR  lpszCookieData,
    _Inout_ LPDWORD lpdwSize
  );
  */
  // NOTE: Even though MSDN documentation does not indicate a calling convention,
  // InternetGetCookieW is declared in SDK headers as __stdcall but is exported
  // from wininet.dll without name mangling, so it is effectively winapi_abi
  let getIECookie = wininet.declare(
    "InternetGetCookieW",
    ctypes.winapi_abi,
    BOOL,
    LPCTSTR,
    LPCTSTR,
    LPCTSTR,
    LPDWORD
  );

  // We need to randomize the cookie to avoid clashing with other cookies
  // that might have been set by previous tests and not properly cleared.
  let date = new Date().getDate();
  const COOKIE = {
    get host() {
      return new URL(this.href).host;
    },
    href: `http://mycookietest.${Math.random()}.com`,
    name: "testcookie",
    value: "testvalue",
    expiry: new Date(new Date().setDate(date + 2)),
  };
  let data = ctypes.char16_t.array()(256);
  let sizeRef = DWORD(256).address();

  registerCleanupFunction(() => {
    // Remove the cookie.
    try {
      let expired = new Date(new Date().setDate(date - 2));
      let rv = setIECookie(
        COOKIE.href,
        COOKIE.name,
        `; expires=${expired.toUTCString()}`
      );
      Assert.ok(rv, "Expired the IE cookie");
      Assert.ok(
        !getIECookie(COOKIE.href, COOKIE.name, data, sizeRef),
        "The cookie has been properly removed"
      );
    } catch (ex) {}

    // Close the library.
    try {
      wininet.close();
    } catch (ex) {}
  });

  // Create the persistent cookie in IE.
  let value = `${COOKIE.value}; expires=${COOKIE.expiry.toUTCString()}`;
  let rv = setIECookie(COOKIE.href, COOKIE.name, value);
  Assert.ok(rv, "Added a persistent IE cookie: " + value);

  // Sanity check the cookie has been created.
  Assert.ok(
    getIECookie(COOKIE.href, COOKIE.name, data, sizeRef),
    "Found the added persistent IE cookie"
  );
  info("Found cookie: " + data.readString());
  Assert.equal(
    data.readString(),
    `${COOKIE.name}=${COOKIE.value}`,
    "Found the expected cookie"
  );

  // Sanity check that there are no cookies.
  Assert.equal(
    Services.cookies.countCookiesFromHost(COOKIE.host),
    0,
    "There are no cookies initially"
  );

  // Migrate cookies.
  await promiseMigration(migrator, MigrationUtils.resourceTypes.COOKIES);

  Assert.equal(
    Services.cookies.countCookiesFromHost(COOKIE.host),
    1,
    "Migrated the expected number of cookies"
  );

  // Now check the cookie details.
  let cookies = Services.cookies.getCookiesFromHost(COOKIE.host, {});
  Assert.ok(cookies.length);
  let foundCookie = cookies[0];

  Assert.equal(foundCookie.name, COOKIE.name);
  Assert.equal(foundCookie.value, COOKIE.value);
  Assert.equal(foundCookie.host, "." + COOKIE.host);
  Assert.equal(foundCookie.expiry, Math.floor(COOKIE.expiry / 1000));
});