Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/widget/xremoteclient/RemoteUtils.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim:expandtab:shiftwidth=2:tabstop=8:
3
 */
4
/* vim:set ts=8 sw=2 et cindent: */
5
/* This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8
9
#include <stdlib.h>
10
#include <string.h>
11
#include <strings.h>
12
#include <unistd.h>
13
#include <limits.h>
14
15
#include "RemoteUtils.h"
16
17
#ifdef IS_BIG_ENDIAN
18
#define TO_LITTLE_ENDIAN32(x) \
19
    ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
20
    (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
21
#else
22
0
#define TO_LITTLE_ENDIAN32(x) (x)
23
#endif
24
25
#ifndef MAX_PATH
26
#ifdef PATH_MAX
27
0
#define MAX_PATH PATH_MAX
28
#else
29
#define MAX_PATH 1024
30
#endif
31
#endif
32
33
/* like strcpy, but return the char after the final null */
34
static char*
35
estrcpy(const char* s, char* d)
36
0
{
37
0
  while (*s)
38
0
    *d++ = *s++;
39
0
40
0
  *d++ = '\0';
41
0
  return d;
42
0
}
43
44
/* Construct a command line from given args and desktop startup ID.
45
 * Returned buffer must be released by free().
46
 */
47
char*
48
ConstructCommandLine(int32_t argc, char **argv,
49
                     const char* aDesktopStartupID,
50
                     int *aCommandLineLength)
51
0
{
52
0
  char cwdbuf[MAX_PATH];
53
0
  if (!getcwd(cwdbuf, MAX_PATH))
54
0
    return nullptr;
55
0
56
0
  // the commandline property is constructed as an array of int32_t
57
0
  // followed by a series of null-terminated strings:
58
0
  //
59
0
  // [argc][offsetargv0][offsetargv1...]<workingdir>\0<argv[0]>\0argv[1]...\0
60
0
  // (offset is from the beginning of the buffer)
61
0
62
0
  static char desktopStartupPrefix[] = " DESKTOP_STARTUP_ID=";
63
0
64
0
  int32_t argvlen = strlen(cwdbuf);
65
0
  for (int i = 0; i < argc; ++i) {
66
0
    int32_t len = strlen(argv[i]);
67
0
    if (i == 0 && aDesktopStartupID) {
68
0
      len += sizeof(desktopStartupPrefix) - 1 + strlen(aDesktopStartupID);
69
0
    }
70
0
    argvlen += len;
71
0
  }
72
0
73
0
  auto* buffer = (int32_t*) malloc(argvlen + argc + 1 +
74
0
                                   sizeof(int32_t) * (argc + 1));
75
0
  if (!buffer)
76
0
    return nullptr;
77
0
78
0
  buffer[0] = TO_LITTLE_ENDIAN32(argc);
79
0
80
0
  auto *bufend = (char*) (buffer + argc + 1);
81
0
82
0
  bufend = estrcpy(cwdbuf, bufend);
83
0
84
0
  for (int i = 0; i < argc; ++i) {
85
0
    buffer[i + 1] = TO_LITTLE_ENDIAN32(bufend - ((char*) buffer));
86
0
    bufend = estrcpy(argv[i], bufend);
87
0
    if (i == 0 && aDesktopStartupID) {
88
0
      bufend = estrcpy(desktopStartupPrefix, bufend - 1);
89
0
      bufend = estrcpy(aDesktopStartupID, bufend - 1);
90
0
    }
91
0
  }
92
0
93
#ifdef DEBUG_command_line
94
  int32_t   debug_argc   = TO_LITTLE_ENDIAN32(*buffer);
95
  char *debug_workingdir = (char*) (buffer + argc + 1);
96
97
  printf("Sending command line:\n"
98
         "  working dir: %s\n"
99
         "  argc:\t%i",
100
         debug_workingdir,
101
         debug_argc);
102
103
  int32_t  *debug_offset = buffer + 1;
104
  for (int debug_i = 0; debug_i < debug_argc; ++debug_i)
105
    printf("  argv[%i]:\t%s\n", debug_i,
106
           ((char*) buffer) + TO_LITTLE_ENDIAN32(debug_offset[debug_i]));
107
#endif
108
109
0
  *aCommandLineLength = bufend - reinterpret_cast<char *>(buffer);
110
0
  return reinterpret_cast<char *>(buffer);
111
0
}