1 /*
2 * Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6
7 #include <stdarg.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include "native_client/src/include/portability_io.h"
12 #include "native_client/src/include/portability_process.h"
13 #include "native_client/src/shared/platform/nacl_check.h"
14 #include "ppapi/cpp/module.h"
15 #include "ppapi/native_client/src/trusted/plugin/utility.h"
16
17 namespace plugin {
18
19 int gNaClPluginDebugPrintEnabled = -1;
20
21 /*
22 * Prints formatted message to the log.
23 */
NaClPluginPrintLog(const char * format,...)24 int NaClPluginPrintLog(const char *format, ...) {
25 va_list arg;
26 int out_size;
27
28 static const int kStackBufferSize = 512;
29 char stack_buffer[kStackBufferSize];
30
31 // Just log locally to stderr if we can't use the nacl interface.
32 if (!GetNaClInterface()) {
33 va_start(arg, format);
34 int rc = vfprintf(stderr, format, arg);
35 va_end(arg);
36 return rc;
37 }
38
39 va_start(arg, format);
40 out_size = vsnprintf(stack_buffer, kStackBufferSize, format, arg);
41 va_end(arg);
42 if (out_size < kStackBufferSize) {
43 GetNaClInterface()->Vlog(stack_buffer);
44 } else {
45 // Message too large for our stack buffer; we have to allocate memory
46 // instead.
47 char *buffer = static_cast<char*>(malloc(out_size + 1));
48 va_start(arg, format);
49 vsnprintf(buffer, out_size + 1, format, arg);
50 va_end(arg);
51 GetNaClInterface()->Vlog(buffer);
52 free(buffer);
53 }
54 return out_size;
55 }
56
57 /*
58 * Currently looks for presence of NACL_PLUGIN_DEBUG and returns
59 * 0 if absent and 1 if present. In the future we may include notions
60 * of verbosity level.
61 */
NaClPluginDebugPrintCheckEnv()62 int NaClPluginDebugPrintCheckEnv() {
63 char* env = getenv("NACL_PLUGIN_DEBUG");
64 return (NULL != env);
65 }
66
IsValidIdentifierString(const char * strval,uint32_t * length)67 bool IsValidIdentifierString(const char* strval, uint32_t* length) {
68 // This function is supposed to recognize valid ECMAScript identifiers,
69 // as described in
70 // http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf
71 // It is currently restricted to only the ASCII subset.
72 // TODO(sehr): Recognize the full Unicode formulation of identifiers.
73 // TODO(sehr): Make this table-driven if efficiency becomes a problem.
74 if (NULL != length) {
75 *length = 0;
76 }
77 if (NULL == strval) {
78 return false;
79 }
80 static const char* kValidFirstChars =
81 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$_";
82 static const char* kValidOtherChars =
83 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz$_"
84 "0123456789";
85 if (NULL == strchr(kValidFirstChars, strval[0])) {
86 return false;
87 }
88 uint32_t pos;
89 for (pos = 1; ; ++pos) {
90 if (0 == pos) {
91 // Unsigned overflow.
92 return false;
93 }
94 int c = strval[pos];
95 if (0 == c) {
96 break;
97 }
98 if (NULL == strchr(kValidOtherChars, c)) {
99 return false;
100 }
101 }
102 if (NULL != length) {
103 *length = pos;
104 }
105 return true;
106 }
107
108 // We cache the NaCl interface pointer and ensure that its set early on, on the
109 // main thread. This allows GetNaClInterface() to be used from non-main threads.
110 static const PPB_NaCl_Private* g_nacl_interface = NULL;
111
GetNaClInterface()112 const PPB_NaCl_Private* GetNaClInterface() {
113 return g_nacl_interface;
114 }
115
SetNaClInterface(const PPB_NaCl_Private * nacl_interface)116 void SetNaClInterface(const PPB_NaCl_Private* nacl_interface) {
117 g_nacl_interface = nacl_interface;
118 }
119
CloseFileHandle(PP_FileHandle file_handle)120 void CloseFileHandle(PP_FileHandle file_handle) {
121 #if NACL_WINDOWS
122 CloseHandle(file_handle);
123 #else
124 close(file_handle);
125 #endif
126 }
127
128 // Converts a PP_FileHandle to a POSIX file descriptor.
ConvertFileDescriptor(PP_FileHandle handle,bool read_only)129 int32_t ConvertFileDescriptor(PP_FileHandle handle, bool read_only) {
130 PLUGIN_PRINTF(("ConvertFileDescriptor, handle=%d\n", handle));
131 #if NACL_WINDOWS
132 int32_t file_desc = NACL_NO_FILE_DESC;
133 // On Windows, valid handles are 32 bit unsigned integers so this is safe.
134 file_desc = reinterpret_cast<intptr_t>(handle);
135 // Convert the Windows HANDLE from Pepper to a POSIX file descriptor.
136 int flags = _O_BINARY;
137 flags |= read_only ? _O_RDONLY : _O_RDWR;
138 int32_t posix_desc = _open_osfhandle(file_desc, flags);
139 if (posix_desc == -1) {
140 // Close the Windows HANDLE if it can't be converted.
141 CloseHandle(reinterpret_cast<HANDLE>(file_desc));
142 return -1;
143 }
144 return posix_desc;
145 #else
146 return handle;
147 #endif
148 }
149
150 } // namespace plugin
151