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 */ 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 */ 62 int NaClPluginDebugPrintCheckEnv() { 63 char* env = getenv("NACL_PLUGIN_DEBUG"); 64 return (NULL != env); 65 } 66 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 112 const PPB_NaCl_Private* GetNaClInterface() { 113 return g_nacl_interface; 114 } 115 116 void SetNaClInterface(const PPB_NaCl_Private* nacl_interface) { 117 g_nacl_interface = nacl_interface; 118 } 119 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. 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