Home | History | Annotate | Download | only in plugin
      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