toolkit/mozapps/update/common/readstrings.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include <limits.h>
michael@0 8 #include <string.h>
michael@0 9 #include <stdio.h>
michael@0 10 #include "readstrings.h"
michael@0 11 #include "errors.h"
michael@0 12
michael@0 13 #ifdef XP_WIN
michael@0 14 # define NS_tfopen _wfopen
michael@0 15 # define OPEN_MODE L"rb"
michael@0 16 #else
michael@0 17 # define NS_tfopen fopen
michael@0 18 # define OPEN_MODE "r"
michael@0 19 #endif
michael@0 20
michael@0 21 // stack based FILE wrapper to ensure that fclose is called.
michael@0 22 class AutoFILE {
michael@0 23 public:
michael@0 24 AutoFILE(FILE *fp) : fp_(fp) {}
michael@0 25 ~AutoFILE() { if (fp_) fclose(fp_); }
michael@0 26 operator FILE *() { return fp_; }
michael@0 27 private:
michael@0 28 FILE *fp_;
michael@0 29 };
michael@0 30
michael@0 31 class AutoCharArray {
michael@0 32 public:
michael@0 33 AutoCharArray(size_t len) { ptr_ = new char[len]; }
michael@0 34 ~AutoCharArray() { delete[] ptr_; }
michael@0 35 operator char *() { return ptr_; }
michael@0 36 private:
michael@0 37 char *ptr_;
michael@0 38 };
michael@0 39
michael@0 40 static const char kNL[] = "\r\n";
michael@0 41 static const char kEquals[] = "=";
michael@0 42 static const char kWhitespace[] = " \t";
michael@0 43 static const char kRBracket[] = "]";
michael@0 44
michael@0 45 static const char*
michael@0 46 NS_strspnp(const char *delims, const char *str)
michael@0 47 {
michael@0 48 const char *d;
michael@0 49 do {
michael@0 50 for (d = delims; *d != '\0'; ++d) {
michael@0 51 if (*str == *d) {
michael@0 52 ++str;
michael@0 53 break;
michael@0 54 }
michael@0 55 }
michael@0 56 } while (*d);
michael@0 57
michael@0 58 return str;
michael@0 59 }
michael@0 60
michael@0 61 static char*
michael@0 62 NS_strtok(const char *delims, char **str)
michael@0 63 {
michael@0 64 if (!*str)
michael@0 65 return nullptr;
michael@0 66
michael@0 67 char *ret = (char*) NS_strspnp(delims, *str);
michael@0 68
michael@0 69 if (!*ret) {
michael@0 70 *str = ret;
michael@0 71 return nullptr;
michael@0 72 }
michael@0 73
michael@0 74 char *i = ret;
michael@0 75 do {
michael@0 76 for (const char *d = delims; *d != '\0'; ++d) {
michael@0 77 if (*i == *d) {
michael@0 78 *i = '\0';
michael@0 79 *str = ++i;
michael@0 80 return ret;
michael@0 81 }
michael@0 82 }
michael@0 83 ++i;
michael@0 84 } while (*i);
michael@0 85
michael@0 86 *str = nullptr;
michael@0 87 return ret;
michael@0 88 }
michael@0 89
michael@0 90 /**
michael@0 91 * Find a key in a keyList containing zero-delimited keys ending with "\0\0".
michael@0 92 * Returns a zero-based index of the key in the list, or -1 if the key is not found.
michael@0 93 */
michael@0 94 static int
michael@0 95 find_key(const char *keyList, char* key)
michael@0 96 {
michael@0 97 if (!keyList)
michael@0 98 return -1;
michael@0 99
michael@0 100 int index = 0;
michael@0 101 const char *p = keyList;
michael@0 102 while (*p)
michael@0 103 {
michael@0 104 if (strcmp(key, p) == 0)
michael@0 105 return index;
michael@0 106
michael@0 107 p += strlen(p) + 1;
michael@0 108 index++;
michael@0 109 }
michael@0 110
michael@0 111 // The key was not found if we came here
michael@0 112 return -1;
michael@0 113 }
michael@0 114
michael@0 115 /**
michael@0 116 * A very basic parser for updater.ini taken mostly from nsINIParser.cpp
michael@0 117 * that can be used by standalone apps.
michael@0 118 *
michael@0 119 * @param path Path to the .ini file to read
michael@0 120 * @param keyList List of zero-delimited keys ending with two zero characters
michael@0 121 * @param numStrings Number of strings to read into results buffer - must be equal to the number of keys
michael@0 122 * @param results Two-dimensional array of strings to be filled in the same order as the keys provided
michael@0 123 * @param section Optional name of the section to read; defaults to "Strings"
michael@0 124 */
michael@0 125 int
michael@0 126 ReadStrings(const NS_tchar *path,
michael@0 127 const char *keyList,
michael@0 128 unsigned int numStrings,
michael@0 129 char results[][MAX_TEXT_LEN],
michael@0 130 const char *section)
michael@0 131 {
michael@0 132 AutoFILE fp = NS_tfopen(path, OPEN_MODE);
michael@0 133
michael@0 134 if (!fp)
michael@0 135 return READ_ERROR;
michael@0 136
michael@0 137 /* get file size */
michael@0 138 if (fseek(fp, 0, SEEK_END) != 0)
michael@0 139 return READ_ERROR;
michael@0 140
michael@0 141 long len = ftell(fp);
michael@0 142 if (len <= 0)
michael@0 143 return READ_ERROR;
michael@0 144
michael@0 145 size_t flen = size_t(len);
michael@0 146 AutoCharArray fileContents(flen + 1);
michael@0 147 if (!fileContents)
michael@0 148 return READ_STRINGS_MEM_ERROR;
michael@0 149
michael@0 150 /* read the file in one swoop */
michael@0 151 if (fseek(fp, 0, SEEK_SET) != 0)
michael@0 152 return READ_ERROR;
michael@0 153
michael@0 154 size_t rd = fread(fileContents, sizeof(char), flen, fp);
michael@0 155 if (rd != flen)
michael@0 156 return READ_ERROR;
michael@0 157
michael@0 158 fileContents[flen] = '\0';
michael@0 159
michael@0 160 char *buffer = fileContents;
michael@0 161 bool inStringsSection = false;
michael@0 162
michael@0 163 unsigned int read = 0;
michael@0 164
michael@0 165 while (char *token = NS_strtok(kNL, &buffer)) {
michael@0 166 if (token[0] == '#' || token[0] == ';') // it's a comment
michael@0 167 continue;
michael@0 168
michael@0 169 token = (char*) NS_strspnp(kWhitespace, token);
michael@0 170 if (!*token) // empty line
michael@0 171 continue;
michael@0 172
michael@0 173 if (token[0] == '[') { // section header!
michael@0 174 ++token;
michael@0 175 char const * currSection = token;
michael@0 176
michael@0 177 char *rb = NS_strtok(kRBracket, &token);
michael@0 178 if (!rb || NS_strtok(kWhitespace, &token)) {
michael@0 179 // there's either an unclosed [Section or a [Section]Moretext!
michael@0 180 // we could frankly decide that this INI file is malformed right
michael@0 181 // here and stop, but we won't... keep going, looking for
michael@0 182 // a well-formed [section] to continue working with
michael@0 183 inStringsSection = false;
michael@0 184 }
michael@0 185 else {
michael@0 186 if (section)
michael@0 187 inStringsSection = strcmp(currSection, section) == 0;
michael@0 188 else
michael@0 189 inStringsSection = strcmp(currSection, "Strings") == 0;
michael@0 190 }
michael@0 191
michael@0 192 continue;
michael@0 193 }
michael@0 194
michael@0 195 if (!inStringsSection) {
michael@0 196 // If we haven't found a section header (or we found a malformed
michael@0 197 // section header), or this isn't the [Strings] section don't bother
michael@0 198 // parsing this line.
michael@0 199 continue;
michael@0 200 }
michael@0 201
michael@0 202 char *key = token;
michael@0 203 char *e = NS_strtok(kEquals, &token);
michael@0 204 if (!e)
michael@0 205 continue;
michael@0 206
michael@0 207 int keyIndex = find_key(keyList, key);
michael@0 208 if (keyIndex >= 0 && (unsigned int)keyIndex < numStrings)
michael@0 209 {
michael@0 210 strncpy(results[keyIndex], token, MAX_TEXT_LEN - 1);
michael@0 211 results[keyIndex][MAX_TEXT_LEN - 1] = '\0';
michael@0 212 read++;
michael@0 213 }
michael@0 214 }
michael@0 215
michael@0 216 return (read == numStrings) ? OK : PARSE_ERROR;
michael@0 217 }
michael@0 218
michael@0 219 // A wrapper function to read strings for the updater.
michael@0 220 // Added for compatibility with the original code.
michael@0 221 int
michael@0 222 ReadStrings(const NS_tchar *path, StringTable *results)
michael@0 223 {
michael@0 224 const unsigned int kNumStrings = 2;
michael@0 225 const char *kUpdaterKeys = "Title\0Info\0";
michael@0 226 char updater_strings[kNumStrings][MAX_TEXT_LEN];
michael@0 227
michael@0 228 int result = ReadStrings(path, kUpdaterKeys, kNumStrings, updater_strings);
michael@0 229
michael@0 230 strncpy(results->title, updater_strings[0], MAX_TEXT_LEN - 1);
michael@0 231 results->title[MAX_TEXT_LEN - 1] = '\0';
michael@0 232 strncpy(results->info, updater_strings[1], MAX_TEXT_LEN - 1);
michael@0 233 results->info[MAX_TEXT_LEN - 1] = '\0';
michael@0 234
michael@0 235 return result;
michael@0 236 }

mercurial