• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4  *
5  * The contents of this file are subject to the Mozilla Public License Version
6  * 1.1 (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  * http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the
13  * License.
14  *
15  * The Original Code is mozilla.org code.
16  *
17  * The Initial Developer of the Original Code is
18  * Netscape Communications Corporation.
19  * Portions created by the Initial Developer are Copyright (C) 1998
20  * the Initial Developer. All Rights Reserved.
21  *
22  * Contributor(s):
23  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either the GNU General Public License Version 2 or later (the "GPL"), or
26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK ***** */
37 
38 #include <string>
39 #include <vector>
40 #include <errno.h>
41 
42 
43 #include "xp.h"
44 
45 #include "format.h"
46 #include "logger.h"
47 
48 extern Logger * logger;
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 // From Google Chrome's string_util.cc
52 
53 // It's possible for functions that use a va_list, such as StringPrintf, to
54 // invalidate the data in it upon use.  The fix is to make a copy of the
55 // structure before using it and use that copy instead.  va_copy is provided
56 // for this purpose.  MSVC does not provide va_copy, so define an
57 // implementation here.  It is not guaranteed that assignment is a copy, so the
58 // StringUtil.__GNUC__ unit test tests this capability.
59 #if defined(COMPILER_GCC)
60 #define GG_VA_COPY(a, b) (va_copy(a, b))
61 #elif defined(_MSC_VER)
62 #define GG_VA_COPY(a, b) (a = b)
63 #endif
64 
65 
66 // The arraysize(arr) macro returns the # of elements in an array arr.
67 // The expression is a compile-time constant, and therefore can be
68 // used in defining new arrays, for example.  If you use arraysize on
69 // a pointer by mistake, you will get a compile-time error.
70 //
71 // One caveat is that arraysize() doesn't accept any array of an
72 // anonymous type or a type defined inside a function.  In these rare
73 // cases, you have to use the unsafe ARRAYSIZE_UNSAFE() macro below.  This is
74 // due to a limitation in C++'s template system.  The limitation might
75 // eventually be removed, but it hasn't happened yet.
76 
77 // This template function declaration is used in defining arraysize.
78 // Note that the function doesn't need an implementation, as we only
79 // use its type.
80 template <typename T, size_t N>
81 char (&ArraySizeHelper(T (&array)[N]))[N];
82 
83 // That gcc wants both of these prototypes seems mysterious. VC, for
84 // its part, can't decide which to use (another mystery). Matching of
85 // template overloads: the final frontier.
86 #ifndef _MSC_VER
87 template <typename T, size_t N>
88 char (&ArraySizeHelper(const T (&array)[N]))[N];
89 #endif
90 
91 #define arraysize(array) (sizeof(ArraySizeHelper(array)))
92 
93 #if defined(_WIN32)
vsnprintf(char * buffer,size_t size,const char * format,va_list arguments)94 inline int vsnprintf(char* buffer, size_t size,
95                      const char* format, va_list arguments) {
96   int length = vsnprintf_s(buffer, size, size - 1, format, arguments);
97   if (length < 0)
98     return _vscprintf(format, arguments);
99   return length;
100 }
101 #else
vsnprintf(char * buffer,size_t size,const char * format,va_list arguments)102 inline int vsnprintf(char* buffer, size_t size,
103                      const char* format, va_list arguments) {
104   return ::vsnprintf(buffer, size, format, arguments);
105 }
106 #endif
107 
108 
109 // Templatized backend for StringPrintF/StringAppendF. This does not finalize
110 // the va_list, the caller is expected to do that.
111 template <class StringType>
StringAppendVT(StringType * dst,const typename StringType::value_type * format,va_list ap)112 static void StringAppendVT(StringType* dst,
113                            const typename StringType::value_type* format,
114                            va_list ap) {
115   // First try with a small fixed size buffer.
116   // This buffer size should be kept in sync with StringUtilTest.GrowBoundary
117   // and StringUtilTest.StringPrintfBounds.
118   typename StringType::value_type stack_buf[1024];
119 
120   va_list ap_copy;
121   GG_VA_COPY(ap_copy, ap);
122 
123 #if !defined(_WIN32)
124   errno = 0;
125 #endif
126   int result = vsnprintf(stack_buf, arraysize(stack_buf), format, ap_copy);
127   va_end(ap_copy);
128 
129   if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) {
130     // It fit.
131     dst->append(stack_buf, result);
132     return;
133   }
134 
135   // Repeatedly increase buffer size until it fits.
136   int mem_length = arraysize(stack_buf);
137   while (true) {
138     if (result < 0) {
139 #if !defined(_WIN32)
140       // On Windows, vsnprintf always returns the number of characters in a
141       // fully-formatted string, so if we reach this point, something else is
142       // wrong and no amount of buffer-doubling is going to fix it.
143       if (errno != 0 && errno != EOVERFLOW)
144 #endif
145       {
146         // If an error other than overflow occurred, it's never going to work.
147         return;
148       }
149       // Try doubling the buffer size.
150       mem_length *= 2;
151     } else {
152       // We need exactly "result + 1" characters.
153       mem_length = result + 1;
154     }
155 
156     if (mem_length > 32 * 1024 * 1024) {
157       // That should be plenty, don't try anything larger.  This protects
158       // against huge allocations when using vsnprintf implementations that
159       // return -1 for reasons other than overflow without setting errno.
160       return;
161     }
162 
163     std::vector<typename StringType::value_type> mem_buf(mem_length);
164 
165     // NOTE: You can only use a va_list once.  Since we're in a while loop, we
166     // need to make a new copy each time so we don't use up the original.
167     GG_VA_COPY(ap_copy, ap);
168     result = vsnprintf(&mem_buf[0], mem_length, format, ap_copy);
169     va_end(ap_copy);
170 
171     if ((result >= 0) && (result < mem_length)) {
172       // It fit.
173       dst->append(&mem_buf[0], result);
174       return;
175     }
176   }
177 }
178 
StringPrintf(const char * format,...)179 std::string StringPrintf(const char* format, ...) {
180   va_list ap;
181   va_start(ap, format);
182   std::string result;
183   StringAppendVT(&result, format, ap);
184   va_end(ap);
185   return result;
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 
190 
FormatNPAPIError(int iError)191 char * FormatNPAPIError(int iError)
192 {
193   static char szError[64];
194   switch (iError)
195   {
196     case NPERR_NO_ERROR:
197       sprintf(szError, "NPERR_NO_ERROR");
198       break;
199     case NPERR_GENERIC_ERROR:
200       sprintf(szError, "NPERR_GENERIC_ERROR");
201       break;
202     case NPERR_INVALID_INSTANCE_ERROR:
203       sprintf(szError, "NPERR_INVALID_INSTANCE_ERROR");
204       break;
205     case NPERR_INVALID_FUNCTABLE_ERROR:
206       sprintf(szError, "NPERR_INVALID_FUNCTABLE_ERROR");
207       break;
208     case NPERR_MODULE_LOAD_FAILED_ERROR:
209       sprintf(szError, "NPERR_MODULE_LOAD_FAILED_ERROR");
210       break;
211     case NPERR_OUT_OF_MEMORY_ERROR:
212       sprintf(szError, "NPERR_OUT_OF_MEMORY_ERROR");
213       break;
214     case NPERR_INVALID_PLUGIN_ERROR:
215       sprintf(szError, "NPERR_INVALID_PLUGIN_ERROR");
216       break;
217     case NPERR_INVALID_PLUGIN_DIR_ERROR:
218       sprintf(szError, "NPERR_INVALID_PLUGIN_DIR_ERROR");
219       break;
220     case NPERR_INCOMPATIBLE_VERSION_ERROR:
221       sprintf(szError, "NPERR_INCOMPATIBLE_VERSION_ERROR");
222       break;
223     case NPERR_INVALID_PARAM:
224       sprintf(szError, "NPERR_INVALID_PARAM");
225       break;
226     case NPERR_INVALID_URL:
227       sprintf(szError, "NPERR_INVALID_URL");
228       break;
229     case NPERR_FILE_NOT_FOUND:
230       sprintf(szError, "NPERR_FILE_NOT_FOUND");
231       break;
232     case NPERR_NO_DATA:
233       sprintf(szError, "NPERR_NO_DATA");
234       break;
235     case NPERR_STREAM_NOT_SEEKABLE:
236       sprintf(szError, "NPERR_STREAM_NOT_SEEKABLE");
237       break;
238     default:
239       sprintf(szError, "Unlisted error");
240       break;
241   }
242   return &szError[0];
243 }
244 
FormatNPAPIReason(int iReason)245 char * FormatNPAPIReason(int iReason)
246 {
247   static char szReason[64];
248   switch (iReason)
249   {
250     case NPRES_DONE:
251       sprintf(szReason, "NPRES_DONE");
252       break;
253     case NPRES_NETWORK_ERR:
254       sprintf(szReason, "NPRES_NETWORK_ERR");
255       break;
256     case NPRES_USER_BREAK:
257       sprintf(szReason, "NPRES_USER_BREAK");
258       break;
259     default:
260       sprintf(szReason, "Unlisted reason");
261       break;
262   }
263   return &szReason[0];
264 }
265 
FormatNPNVariable(NPNVariable var)266 char * FormatNPNVariable(NPNVariable var)
267 {
268   static char szVar[80];
269   switch (var)
270   {
271     case NPNVxDisplay:
272       sprintf(szVar, "%i -- NPNVxDisplay", var);
273       break;
274     case NPNVxtAppContext:
275       sprintf(szVar, "%i -- NPNVxtAppContext", var);
276       break;
277     case NPNVnetscapeWindow:
278       sprintf(szVar, "%i -- NPNVnetscapeWindow", var);
279       break;
280     case NPNVjavascriptEnabledBool:
281       sprintf(szVar, "%i -- NPNVjavascriptEnabledBool", var);
282       break;
283     case NPNVasdEnabledBool:
284       sprintf(szVar, "%i -- NPNVasdEnabledBool", var);
285       break;
286     case NPNVisOfflineBool:
287       sprintf(szVar, "%i -- NPNVisOfflineBool", var);
288       break;
289     default:
290       sprintf(szVar, "%i -- Unlisted variable", var);
291       break;
292   }
293   return &szVar[0];
294 }
295 
FormatNPPVariable(NPPVariable var)296 char * FormatNPPVariable(NPPVariable var)
297 {
298   static char szVar[80];
299   switch (var)
300   {
301     case NPPVpluginNameString:
302       sprintf(szVar, "%i -- NPPVpluginNameString", var);
303       break;
304     case NPPVpluginDescriptionString:
305       sprintf(szVar, "%i -- NPPVpluginDescriptionString?", var);
306       break;
307     case NPPVpluginWindowBool:
308       sprintf(szVar, "%i -- NPPVpluginWindowBool?", var);
309       break;
310     case NPPVpluginTransparentBool:
311       sprintf(szVar, "%i -- NPPVpluginTransparentBool?", var);
312       break;
313     case NPPVjavaClass:
314       sprintf(szVar, "%i -- NPPVjavaClass?", var);
315       break;
316     case NPPVpluginWindowSize:
317       sprintf(szVar, "%i -- NPPVpluginWindowSize?", var);
318       break;
319     case NPPVpluginTimerInterval:
320       sprintf(szVar, "%i -- NPPVpluginTimerInterval?", var);
321       break;
322     case NPPVpluginScriptableInstance:
323       sprintf(szVar, "%i -- NPPVpluginScriptableInstance?", var);
324       break;
325     case NPPVpluginScriptableIID:
326       sprintf(szVar, "%i -- NPPVpluginScriptableIID?", var);
327       break;
328     default:
329       sprintf(szVar, "%i -- Unlisted variable?", var);
330       break;
331   }
332   return &szVar[0];
333 }
334 
FormatPCHARArgument(char * szBuf,int iLength,LogArgumentStruct * parg)335 BOOL FormatPCHARArgument(char * szBuf, int iLength, LogArgumentStruct * parg)
336 {
337   if(iLength <= parg->iLength)
338     return FALSE;
339 
340   if(parg->pData == NULL)
341     sprintf(szBuf, "%#08lx", parg->dwArg);
342   else
343     sprintf(szBuf, "%#08lx(\"%s\")", parg->dwArg, (char *)parg->pData);
344   return TRUE;
345 }
346 
FormatBOOLArgument(char * szBuf,int iLength,LogArgumentStruct * parg)347 BOOL FormatBOOLArgument(char * szBuf, int iLength, LogArgumentStruct * parg)
348 {
349   if(iLength <= 8)
350     return FALSE;
351 
352   sprintf(szBuf, "%s", ((NPBool)parg->dwArg == TRUE) ? "TRUE" : "FALSE");
353   return TRUE;
354 }
355 
FormatPBOOLArgument(char * szBuf,int iLength,LogArgumentStruct * parg)356 BOOL FormatPBOOLArgument(char * szBuf, int iLength, LogArgumentStruct * parg)
357 {
358   if(iLength <= 8)
359     return FALSE;
360 
361   sprintf(szBuf, "%#08lx(%s)", parg->dwArg, (*((NPBool *)parg->pData) == TRUE) ? "TRUE" : "FALSE");
362   return TRUE;
363 }
364 
makeAbbreviatedString(char * szBuf,int iSize,DWORD dwArg,int iLength,int iWrap)365 static void makeAbbreviatedString(char * szBuf, int iSize, DWORD dwArg, int iLength, int iWrap)
366 {
367   if(dwArg == 0L)
368   {
369     szBuf[0] = '\0';
370     return;
371   }
372 
373   if(iLength > iWrap)
374   {
375     int iRealWrap = (iSize > iWrap) ? iWrap : (iSize - 4);
376     memcpy((LPVOID)&szBuf[0], (LPVOID)dwArg, iRealWrap);
377     szBuf[iRealWrap]     = '.';
378     szBuf[iRealWrap + 1] = '.';
379     szBuf[iRealWrap + 2] = '.';
380     szBuf[iRealWrap + 3] = '\0';
381   }
382   else
383   {
384     if(iLength >= iSize)
385     {
386       memcpy((LPVOID)&szBuf[0], (LPVOID)dwArg, iSize - 4);
387       szBuf[iSize]     = '.';
388       szBuf[iSize + 1] = '.';
389       szBuf[iSize + 2] = '.';
390       szBuf[iSize + 3] = '\0';
391     }
392     else
393     {
394       memcpy((LPVOID)&szBuf[0], (LPVOID)dwArg, iLength);
395       szBuf[iLength] = '\0';
396     }
397   }
398 }
399 
makeLogItemStruct(NPAPI_Action action,DWORD dw1,DWORD dw2,DWORD dw3,DWORD dw4,DWORD dw5,DWORD dw6,DWORD dw7,BOOL bShort)400 LogItemStruct * makeLogItemStruct(NPAPI_Action action,
401                                   DWORD dw1, DWORD dw2, DWORD dw3, DWORD dw4,
402                                   DWORD dw5, DWORD dw6, DWORD dw7, BOOL bShort)
403 {
404   int iWrap = 64;
405 
406   LogItemStruct * plis = new LogItemStruct;
407   if(plis == NULL)
408     return NULL;
409 
410   plis->action = action;
411   plis->arg1.dwArg = dw1;
412   plis->arg2.dwArg = dw2;
413   plis->arg3.dwArg = dw3;
414   plis->arg4.dwArg = dw4;
415   plis->arg5.dwArg = dw5;
416   plis->arg6.dwArg = dw6;
417   plis->arg7.dwArg = dw7;
418 
419   char szTarget[1024] = {'\0'};
420   char szBuf[1024] = {'\0'};
421 
422   if(bShort)
423     return plis;
424 
425   switch (action)
426   {
427     case action_invalid:
428       break;
429 
430     // NPN action
431     case action_npn_version:
432       plis->arg1.pData = new int[1];
433       *(int*)(plis->arg1.pData) = *((int*)dw1);
434       plis->arg1.iLength = sizeof(int);
435 
436       plis->arg2.pData = new int[1];
437       *(int*)(plis->arg2.pData) = *((int*)dw2);
438       plis->arg2.iLength = sizeof(int);
439 
440       plis->arg3.pData = new int[1];
441       *(int*)(plis->arg3.pData) = *((int*)dw3);
442       plis->arg3.iLength = sizeof(int);
443 
444       plis->arg4.pData = new int[1];
445       *(int*)(plis->arg4.pData) = *((int*)dw4);
446       plis->arg4.iLength = sizeof(int);
447 
448       break;
449     case action_npn_get_url_notify:
450       if(dw2 != 0L)
451       {
452         plis->arg2.iLength = strlen((char *)dw2) + 1;
453         plis->arg2.pData = new char[plis->arg2.iLength];
454         memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
455       }
456 
457       if(dw3 != 0L)
458       {
459         makeAbbreviatedString(szTarget, sizeof(szTarget), dw3, strlen((char *)dw3), iWrap);
460         plis->arg3.iLength = strlen(szTarget) + 1;
461         plis->arg3.pData = new char[plis->arg3.iLength];
462         memcpy(plis->arg3.pData, (LPVOID)&szTarget[0], plis->arg3.iLength);
463       }
464       break;
465     case action_npn_get_url:
466     {
467       if(dw2 != 0L)
468       {
469         plis->arg2.iLength = strlen((char *)dw2) + 1;
470         plis->arg2.pData = new char[plis->arg2.iLength];
471         memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
472       }
473 
474       if(dw3 != 0L)
475       {
476         makeAbbreviatedString(szTarget, sizeof(szTarget), dw3, strlen((char *)dw3), iWrap);
477         plis->arg3.iLength = strlen(szTarget) + 1;
478         plis->arg3.pData = new char[plis->arg3.iLength];
479         memcpy(plis->arg3.pData, (LPVOID)&szTarget[0], plis->arg3.iLength);
480       }
481       break;
482     }
483     case action_npn_post_url_notify:
484     {
485       if(dw2 != 0L)
486       {
487         plis->arg2.iLength = strlen((char *)dw2) + 1;
488         plis->arg2.pData = new char[plis->arg2.iLength];
489         memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
490       }
491 
492       if(dw3 != 0L)
493       {
494         makeAbbreviatedString(szTarget, sizeof(szTarget), dw3, strlen((char *)dw3), iWrap);
495         plis->arg3.iLength = strlen(szTarget) + 1;
496         plis->arg3.pData = new char[plis->arg3.iLength];
497         memcpy(plis->arg3.pData, (LPVOID)&szTarget[0], plis->arg3.iLength);
498       }
499 
500       makeAbbreviatedString(szBuf, sizeof(szBuf), dw5, strlen((char *)dw5), iWrap);
501       plis->arg5.iLength = (int)dw4 + 1;
502       plis->arg5.pData = new char[plis->arg5.iLength];
503       memcpy(plis->arg5.pData, (LPVOID)&szBuf[0], plis->arg5.iLength);
504 
505       break;
506     }
507     case action_npn_post_url:
508     {
509       if(dw2 != 0L)
510       {
511         plis->arg2.iLength = strlen((char *)dw2) + 1;
512         plis->arg2.pData = new char[plis->arg2.iLength];
513         memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
514       }
515 
516       if(dw3 != 0L)
517       {
518         makeAbbreviatedString(szTarget, sizeof(szTarget), dw3, strlen((char *)dw3), iWrap);
519         plis->arg3.iLength = strlen(szTarget) + 1;
520         plis->arg3.pData = new char[plis->arg3.iLength];
521         memcpy(plis->arg3.pData, (LPVOID)&szTarget[0], plis->arg3.iLength);
522       }
523 
524       makeAbbreviatedString(szBuf, sizeof(szBuf), dw5, strlen((char *)dw5), iWrap);
525       plis->arg5.iLength = (int)dw4 + 1;
526       plis->arg5.pData = new char[plis->arg5.iLength];
527       memcpy(plis->arg5.pData, (LPVOID)&szBuf[0], plis->arg5.iLength);
528 
529       break;
530     }
531     case action_npn_new_stream:
532     {
533       if(dw2 != 0L)
534       {
535         plis->arg2.iLength = strlen((char *)dw2) + 1;
536         plis->arg2.pData = new char[plis->arg2.iLength];
537         memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
538       }
539 
540       makeAbbreviatedString(szTarget, sizeof(szTarget), dw3, strlen((char *)dw3), iWrap);
541       plis->arg3.iLength = strlen(szTarget) + 1;
542       plis->arg3.pData = new char[plis->arg3.iLength];
543       memcpy(plis->arg3.pData, (LPVOID)&szTarget[0], plis->arg3.iLength);
544 
545       plis->arg4.pData = new char[sizeof(DWORD)];
546       plis->arg4.iLength = sizeof(DWORD);
547       memcpy(plis->arg4.pData, (LPVOID)dw4, plis->arg4.iLength);
548 
549       break;
550     }
551     case action_npn_destroy_stream:
552       break;
553     case action_npn_request_read:
554       break;
555     case action_npn_write:
556     {
557       makeAbbreviatedString(szBuf, sizeof(szBuf), dw4, strlen((char *)dw4), iWrap);
558       plis->arg4.iLength = strlen(szBuf) + 1;
559       plis->arg4.pData = new char[plis->arg4.iLength];
560       memcpy(plis->arg4.pData, (LPVOID)&szBuf[0], plis->arg4.iLength);
561       break;
562     }
563     case action_npn_status:
564       if(dw2 != 0L)
565       {
566         plis->arg2.iLength = strlen((char *)dw2) + 1;
567         plis->arg2.pData = new char[plis->arg2.iLength];
568         memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
569       }
570       break;
571     case action_npn_user_agent:
572       break;
573     case action_npn_mem_alloc:
574       break;
575     case action_npn_mem_free:
576       break;
577     case action_npn_mem_flush:
578       break;
579     case action_npn_reload_plugins:
580       break;
581     case action_npn_get_java_env:
582       break;
583     case action_npn_get_java_peer:
584       break;
585     case action_npn_get_value:
586       plis->arg3.iLength = sizeof(DWORD);
587       plis->arg3.pData = new char[plis->arg3.iLength];
588       memcpy(plis->arg3.pData, (LPVOID)dw3, plis->arg3.iLength);
589       break;
590     case action_npn_set_value:
591       if(((NPPVariable)dw2 == NPPVpluginNameString) || ((NPPVariable)dw2 == NPPVpluginDescriptionString))
592       {
593         makeAbbreviatedString(szBuf, sizeof(szBuf), dw3, strlen((char *)dw3), iWrap);
594         plis->arg3.iLength = strlen(szBuf) + 1;
595         plis->arg3.pData = new char[plis->arg3.iLength];
596         memcpy(plis->arg3.pData, (LPVOID)&szBuf[0], plis->arg3.iLength);
597       }
598       else if(((NPPVariable)dw2 == NPPVpluginWindowBool) || ((NPPVariable)dw2 == NPPVpluginTransparentBool))
599       {
600         plis->arg3.iLength = sizeof(NPBool);
601         plis->arg3.pData = new char[plis->arg3.iLength];
602         memcpy(plis->arg3.pData, (LPVOID)&dw3, plis->arg3.iLength);
603       }
604       else if((NPPVariable)dw2 == NPPVpluginWindowSize)
605       {
606         plis->arg3.iLength = sizeof(NPSize);
607         plis->arg3.pData = new char[plis->arg3.iLength];
608         memcpy(plis->arg3.pData, (LPVOID)dw3, plis->arg3.iLength);
609       }
610       break;
611     case action_npn_invalidate_rect:
612     {
613       plis->arg2.iLength = sizeof(NPRect);
614       plis->arg2.pData = new char[plis->arg2.iLength];
615       memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
616       break;
617     }
618     case action_npn_invalidate_region:
619       break;
620     case action_npn_force_redraw:
621       break;
622 
623     // NPP action
624     case action_npp_new:
625       plis->arg1.iLength = strlen((char *)dw1) + 1;
626       plis->arg1.pData = new char[plis->arg1.iLength];
627       memcpy(plis->arg1.pData, (LPVOID)dw1, plis->arg1.iLength);
628       break;
629     case action_npp_destroy:
630       plis->arg2.iLength = sizeof(DWORD);
631       plis->arg2.pData = new char[plis->arg2.iLength];
632       memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
633       break;
634     case action_npp_set_window:
635       plis->arg2.iLength = sizeof(NPWindow);
636       plis->arg2.pData = new char[plis->arg2.iLength];
637       memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
638       break;
639     case action_npp_new_stream:
640       plis->arg2.iLength = strlen((char *)dw2) + 1;
641       plis->arg2.pData = new char[plis->arg2.iLength];
642       memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
643 
644       plis->arg5.iLength = sizeof(uint16);
645       plis->arg5.pData = new char[plis->arg5.iLength];
646       memcpy(plis->arg5.pData, (LPVOID)dw5, plis->arg5.iLength);
647       break;
648     case action_npp_destroy_stream:
649       break;
650     case action_npp_stream_as_file:
651       plis->arg3.iLength = strlen((char *)dw3) + 1;
652       plis->arg3.pData = new char[plis->arg3.iLength];
653       memcpy(plis->arg3.pData, (LPVOID)dw3, plis->arg3.iLength);
654       break;
655     case action_npp_write_ready:
656       break;
657     case action_npp_write:
658     {
659       if(dw5 != 0L)
660       {
661         makeAbbreviatedString(szBuf, sizeof(szBuf), dw5, strlen((char *)dw5), iWrap);
662         plis->arg5.iLength = strlen(szBuf) + 1;
663         plis->arg5.pData = new char[plis->arg5.iLength];
664         memcpy(plis->arg5.pData, (LPVOID)&szBuf[0], plis->arg5.iLength);
665       }
666       break;
667     }
668     case action_npp_print:
669       break;
670     case action_npp_handle_event:
671       break;
672     case action_npp_url_notify:
673       plis->arg2.iLength = strlen((char *)dw2) + 1;
674       plis->arg2.pData = new char[plis->arg2.iLength];
675       memcpy(plis->arg2.pData, (LPVOID)dw2, plis->arg2.iLength);
676       break;
677     case action_npp_get_java_class:
678       break;
679     case action_npp_get_value:
680       break;
681     case action_npp_set_value:
682       break;
683 
684     default:
685       break;
686   }
687 
688   return plis;
689 }
690 
freeLogItemStruct(LogItemStruct * lis)691 void freeLogItemStruct(LogItemStruct * lis)
692 {
693   if(lis)
694     delete lis;
695 }
696 
formatLogItem(LogItemStruct * plis,std::string * output,BOOL bDOSStyle)697 void formatLogItem(LogItemStruct * plis, std::string* output, BOOL bDOSStyle)
698 {
699   static char szEOL[8];
700   static char szEOI[256];
701   static char szEndOfItem[] = "";
702 
703   if(bDOSStyle)
704   {
705     strcpy(szEOL, "\r\n");
706     //strcpy(szEOI, szEndOfItem);
707     //strcat(szEOI, "\r\n");
708   }
709   else
710   {
711     strcpy(szEOL, "\n");
712     //strcpy(szEOI, szEndOfItem);
713     //strcat(szEOI, "\n");
714   }
715 
716   DWORD dw1 = plis->arg1.dwArg;
717   DWORD dw2 = plis->arg2.dwArg;
718   DWORD dw3 = plis->arg3.dwArg;
719   DWORD dw4 = plis->arg4.dwArg;
720   DWORD dw5 = plis->arg5.dwArg;
721   DWORD dw6 = plis->arg6.dwArg;
722   DWORD dw7 = plis->arg7.dwArg;
723 
724   char sz1[1024] = {'\0'};
725   char sz2[1024] = {'\0'};
726   char sz3[1024] = {'\0'};
727   char sz4[1024] = {'\0'};
728   char sz5[1024] = {'\0'};
729   char sz6[1024] = {'\0'};
730 
731   switch (plis->action)
732   {
733     case action_invalid:
734       break;
735 
736     // NPN action
737     case action_npn_version:
738       if((plis->arg1.pData != NULL)&&(plis->arg2.pData != NULL)&&(plis->arg3.pData != NULL)&&(plis->arg4.pData != NULL))
739         *output = StringPrintf("NPN_Version(%#08lx, %#08lx, %#08lx, %#08lx)", dw1,dw2,dw3,dw4);
740       else
741         *output = StringPrintf("NPN_Version(%#08lx, %#08lx, %#08lx, %#08lx)", dw1,dw2,dw3,dw4);
742       break;
743     case action_npn_get_url_notify:
744     {
745       FormatPCHARArgument(sz2, sizeof(sz2), &plis->arg2);
746       FormatPCHARArgument(sz3, sizeof(sz3), &plis->arg3);
747       *output = StringPrintf("NPN_GetURLNotify(%#08lx, %s, %s, %#08lx)", dw1,sz2,sz3,dw4);
748       break;
749     }
750     case action_npn_get_url:
751     {
752       FormatPCHARArgument(sz2, sizeof(sz2), &plis->arg2);
753       FormatPCHARArgument(sz3, sizeof(sz3), &plis->arg3);
754       *output = StringPrintf("NPN_GetURL(%#08lx, %s, %s)", dw1,sz2,sz3);
755       break;
756     }
757     case action_npn_post_url_notify:
758     {
759       FormatPCHARArgument(sz2, sizeof(sz2), &plis->arg2);
760       FormatPCHARArgument(sz3, sizeof(sz3), &plis->arg3);
761       FormatPCHARArgument(sz5, sizeof(sz5), &plis->arg5);
762       FormatBOOLArgument(sz6, sizeof(sz6), &plis->arg6);
763 
764       *output = StringPrintf("NPN_PostURLNotify(%#08lx, %s, %s, %li, %s, %s, %#08lx)",
765                dw1,sz2,sz3,(uint32)dw4,sz5,sz6,dw7);
766       break;
767     }
768     case action_npn_post_url:
769     {
770       FormatPCHARArgument(sz2, sizeof(sz2), &plis->arg2);
771       FormatPCHARArgument(sz3, sizeof(sz3), &plis->arg3);
772       FormatPCHARArgument(sz5, sizeof(sz5), &plis->arg5);
773       FormatBOOLArgument(sz6, sizeof(sz6), &plis->arg6);
774 
775       *output = StringPrintf("NPN_PostURL(%#08lx, %s, %s, %li, %s, %s)",
776                dw1,sz2,sz3,(uint32)dw4,sz5,sz6);
777       break;
778     }
779     case action_npn_new_stream:
780     {
781       FormatPCHARArgument(sz2, sizeof(sz2), &plis->arg2);
782       FormatPCHARArgument(sz3, sizeof(sz3), &plis->arg3);
783       if(plis->arg4.pData != NULL)
784         *output = StringPrintf("NPN_NewStream(%#08lx, %s, %s, %#08lx(%#08lx))",
785                  dw1, sz2,sz3,dw4,*(DWORD *)plis->arg4.pData);
786       else
787         *output = StringPrintf("NPN_NewStream(%#08lx, \"%s\", \"%s\", %#08lx)", dw1, sz2,sz3,dw4);
788       break;
789     }
790     case action_npn_destroy_stream:
791       *output = StringPrintf("NPN_DestroyStream(%#08lx, %#08lx, %s)", dw1,dw2,FormatNPAPIReason((int)dw3));
792       break;
793     case action_npn_request_read:
794       *output = StringPrintf("NPN_RequestRead(%#08lx, %#08lx)", dw1, dw2);
795       break;
796     case action_npn_write:
797     {
798       FormatPCHARArgument(sz4, sizeof(sz4), &plis->arg4);
799       *output = StringPrintf("NPN_Write(%#08lx, %#08lx, %li, %s)", dw1, dw2, (int32)dw3, sz4);
800       break;
801     }
802     case action_npn_status:
803     {
804       FormatPCHARArgument(sz2, sizeof(sz2), &plis->arg2);
805       *output = StringPrintf("NPN_Status(%#08lx, %s)", dw1, sz2);
806       break;
807     }
808     case action_npn_user_agent:
809       *output = StringPrintf("NPN_UserAgent(%#08lx)", dw1);
810       break;
811     case action_npn_mem_alloc:
812       *output = StringPrintf("NPN_MemAlloc(%li)", dw1);
813       break;
814     case action_npn_mem_free:
815       *output = StringPrintf("NPN_MemFree(%#08lx)", dw1);
816       break;
817     case action_npn_mem_flush:
818       *output = StringPrintf("NPN_MemFlush(%li)", dw1);
819       break;
820     case action_npn_reload_plugins:
821     {
822       FormatBOOLArgument(sz1, sizeof(sz1), &plis->arg1);
823       *output = StringPrintf("NPN_ReloadPlugins(%s)", sz1);
824       break;
825     }
826     case action_npn_get_java_env:
827       *output = StringPrintf("NPN_GetJavaEnv()");
828       break;
829     case action_npn_get_java_peer:
830       *output = StringPrintf("NPN_GetJavaPeer(%#08lx)", dw1);
831       break;
832     case action_npn_get_value:
833     {
834       switch(dw2)
835       {
836         case NPNVxDisplay:
837         case NPNVxtAppContext:
838         case NPNVnetscapeWindow:
839           if(dw3 != 0L)
840             *output = StringPrintf("NPN_GetValue(%#08lx, %s, %#08lx(%#08lx))",dw1,FormatNPNVariable((NPNVariable)dw2),dw3,*(DWORD *)dw3);
841           else
842             *output = StringPrintf("NPN_GetValue(%#08lx, %s, %#08lx)",dw1,FormatNPNVariable((NPNVariable)dw2),dw3);
843           break;
844         case NPNVjavascriptEnabledBool:
845         case NPNVasdEnabledBool:
846         case NPNVisOfflineBool:
847           if(dw3 != 0L)
848             *output = StringPrintf("NPN_GetValue(%#08lx, %s, %#08lx(%s))",
849                      dw1,FormatNPNVariable((NPNVariable)dw2),dw3,
850                      (((NPBool)*(DWORD *)dw3) == TRUE) ? "TRUE" : "FALSE");
851           else
852             *output = StringPrintf("NPN_GetValue(%#08lx, %s, %#08lx)",dw1,FormatNPNVariable((NPNVariable)dw2),dw3);
853           break;
854         default:
855           break;
856       }
857       break;
858     }
859     case action_npn_set_value:
860 
861       if(((NPPVariable)dw2 == NPPVpluginNameString) || ((NPPVariable)dw2 == NPPVpluginDescriptionString))
862       {
863         FormatPCHARArgument(sz3, sizeof(sz3), &plis->arg3);
864         *output = StringPrintf("NPN_SetValue(%#08lx, %s, %s)", dw1,FormatNPPVariable((NPPVariable)dw2),sz3);
865       }
866       else if(((NPPVariable)dw2 == NPPVpluginWindowBool) || ((NPPVariable)dw2 == NPPVpluginTransparentBool))
867       {
868         FormatPBOOLArgument(sz3, sizeof(sz3), &plis->arg3);
869         *output = StringPrintf("NPN_SetValue(%#08lx, %s, %s)",
870                  dw1,FormatNPPVariable((NPPVariable)dw2),sz3);
871       }
872       else if((NPPVariable)dw2 == NPPVpluginWindowSize)
873       {
874         if(plis->arg3.pData != NULL)
875         {
876           int32 iWidth = ((NPSize *)plis->arg3.pData)->width;
877           int32 iHeight = ((NPSize *)plis->arg3.pData)->height;
878           *output = StringPrintf("NPN_SetValue(%#08lx, %s, %#08lx(%li,%li))",
879                    dw1,FormatNPPVariable((NPPVariable)dw2),dw3,iWidth,iHeight);
880         }
881         else
882           *output = StringPrintf("NPN_SetValue(%#08lx, %s, %#08lx(?,?))",
883                    dw1,FormatNPPVariable((NPPVariable)dw2),dw3);
884       }
885       else
886         *output = StringPrintf("NPN_SetValue(%#08lx, %s, %#08lx(What is it?))", dw1,FormatNPPVariable((NPPVariable)dw2),dw3);
887       break;
888     case action_npn_invalidate_rect:
889     {
890       if(plis->arg2.pData != NULL)
891       {
892         uint16 top    = ((NPRect *)plis->arg2.pData)->top;
893         uint16 left   = ((NPRect *)plis->arg2.pData)->left;
894         uint16 bottom = ((NPRect *)plis->arg2.pData)->bottom;
895         uint16 right  = ((NPRect *)plis->arg2.pData)->right;
896         *output = StringPrintf("NPN_InvalidateRect(%#08lx, %#08lx(%u,%u;%u,%u)", dw1,dw2,top,left,bottom,right);
897       }
898       else
899         *output = StringPrintf("NPN_InvalidateRect(%#08lx, %#08lx(?,?,?,?)", dw1,dw2);
900       break;
901     }
902     case action_npn_invalidate_region:
903       *output = StringPrintf("NPN_InvalidateRegion(%#08lx, %#08lx)", dw1,dw2);
904       break;
905     case action_npn_force_redraw:
906       *output = StringPrintf("NPN_ForceRedraw(%#08lx)", dw1);
907       break;
908     case action_npn_enumerate:
909       *output = StringPrintf("NPN_Enumerate()");
910       break;
911     case action_npn_pop_popups_enabled_state:
912       *output = StringPrintf("NPN_PopPopupsEnabledState()");
913       break;
914     case action_npn_push_popups_enabled_state:
915       *output = StringPrintf("NPN_PushPopupsEnabledState()");
916       break;
917     case action_npn_set_exception:
918       *output = StringPrintf("NPN_SetException(%s)", dw1);
919       break;
920     case action_npn_has_method:
921       *output = StringPrintf("NPN_HasMethod(%d)", dw1);
922       break;
923     case action_npn_has_property:
924       *output = StringPrintf("NPN_HasProperty(%d)", dw1);
925       break;
926     case action_npn_remove_property:
927       *output = StringPrintf("NPN_RemoveProperty(%d)", dw1);
928       break;
929     case action_npn_set_property:
930       *output = StringPrintf("NPN_SetProperty(%d)", dw1);
931       break;
932     case action_npn_get_property:
933       *output = StringPrintf("NPN_GetProperty(%d)", dw1);
934       break;
935     case action_npn_evaluate:
936       *output = StringPrintf("NPN_Evaluate(%s)", dw1);
937       break;
938     case action_npn_invoke_default:
939       *output = StringPrintf("NPN_InvokeDefault(%#08lx)", dw1);
940       break;
941     case action_npn_invoke:
942       *output = StringPrintf("NPN_Invoke(%#08lx)", dw1);
943       break;
944     case action_npn_release_object:
945       *output = StringPrintf("NPN_ReleaseObject(%d)", dw1);
946       break;
947     case action_npn_retain_object:
948       *output = StringPrintf("NPN_RetainObject(%d)", dw1);
949       break;
950     case action_npn_create_object:
951       *output = StringPrintf("NPN_CreateObject(%#08lx)", dw1);
952       break;
953     case action_npn_int_from_identifier:
954       *output = StringPrintf("NPN_IntFromIdentifier(%d)", dw1);
955       break;
956     case action_npn_utf8_from_identifier:
957       *output = StringPrintf("NPN_UTF8FromIdentifier(%d)", dw1);
958       break;
959     case action_npn_identifier_is_string:
960       *output = StringPrintf("NPN_IdentifierIsString(%d)", dw1);
961       break;
962     case action_npn_get_int_identifer:
963       *output = StringPrintf("NPN_GetIntIdentifier(%d)", dw1);
964       break;
965     case action_npn_get_string_identifiers:
966       *output = StringPrintf("NPN_GetStringIdentifier()");
967       break;
968 
969     // NPP action
970     case action_npp_new:
971     {
972       char szMode[16];
973       switch (dw3)
974       {
975         case NP_EMBED:
976           strcpy(szMode, "NP_EMBED");
977           break;
978         case NP_FULL:
979           strcpy(szMode, "NP_FULL");
980           break;
981         default:
982           strcpy(szMode, "[Invalid mode]");
983           break;
984       }
985       *output = StringPrintf("NPP_New(\"%s\", %#08lx, %s, %i, %#08lx, %#08lx, %#08lx)",
986                (char *)dw1,dw2,szMode,(int)dw4,dw5,dw6,dw7);
987       break;
988     }
989     case action_npp_destroy:
990       *output = StringPrintf("NPP_Destroy(%#08lx, %#08lx(%#08lx))", dw1, dw2, *(DWORD *)plis->arg2.pData);
991       break;
992     case action_npp_set_window:
993     {
994       char szWindow[512];
995 
996       if(plis->arg2.pData != NULL)
997       {
998         char szType[80];
999         switch (((NPWindow*)plis->arg2.pData)->type)
1000         {
1001           case NPWindowTypeWindow:
1002             sprintf(szType, "NPWindowTypeWindow");
1003             break;
1004           case NPWindowTypeDrawable:
1005             sprintf(szType, "NPWindowTypeDrawable");
1006             break;
1007           default:
1008             sprintf(szType, "[Unlisted type]");
1009             break;
1010         }
1011         sprintf(szWindow, "NPWindow: %#08lx, (%li,%li), (%li,%li), (%i,%i,%i,%i), %s",
1012                  ((NPWindow*)plis->arg2.pData)->window,
1013                  ((NPWindow*)plis->arg2.pData)->x,
1014                  ((NPWindow*)plis->arg2.pData)->y,
1015                  ((NPWindow*)plis->arg2.pData)->width,
1016                  ((NPWindow*)plis->arg2.pData)->height,
1017                  ((NPWindow*)plis->arg2.pData)->clipRect.top,
1018                  ((NPWindow*)plis->arg2.pData)->clipRect.left,
1019                  ((NPWindow*)plis->arg2.pData)->clipRect.bottom,
1020                  ((NPWindow*)plis->arg2.pData)->clipRect.right, szType);
1021         *output = StringPrintf("NPP_SetWindow(%#08lx, %#08lx) %s", dw1,dw2,szWindow);
1022       }
1023       else
1024         *output = StringPrintf("NPP_SetWindow(%#08lx, %#08lx)", dw1,dw2);
1025 
1026       break;
1027     }
1028     case action_npp_new_stream:
1029     {
1030       switch (*(int16 *)plis->arg5.pData)
1031       {
1032         case NP_NORMAL:
1033           sprintf(sz5, "NP_NORMAL");
1034           break;
1035         case NP_ASFILEONLY:
1036           sprintf(sz5, "NP_ASFILEONLY");
1037           break;
1038         case NP_ASFILE:
1039           sprintf(sz5, "NP_ASFILE");
1040           break;
1041         default:
1042           sprintf(sz5, "[Unlisted type]");
1043           break;
1044       }
1045       FormatPCHARArgument(sz2, sizeof(sz2), &plis->arg2);
1046       *output = StringPrintf("NPP_NewStream(%#08lx, %s, %#08lx (%s), %s, %s)", dw1, sz2, dw3,
1047                ((NPStream*)dw3)->url, ((NPBool)dw4 == TRUE) ? "TRUE" : "FALSE", sz5);
1048       break;
1049     }
1050     case action_npp_destroy_stream:
1051       *output = StringPrintf("NPP_DestroyStream(%#08lx, %#08lx, %s)", dw1,dw2,FormatNPAPIReason((int)dw3));
1052       break;
1053     case action_npp_stream_as_file:
1054       FormatPCHARArgument(sz3, sizeof(sz3), &plis->arg3);
1055       *output = StringPrintf("NPP_StreamAsFile(%#08lx, %#08lx, %s)", dw1,dw2,sz3);
1056       break;
1057     case action_npp_write_ready:
1058       *output = StringPrintf("NPP_WriteReady(%#08lx, %#08lx)", dw1,dw2);
1059       break;
1060     case action_npp_write:
1061     {
1062       FormatPCHARArgument(sz5, sizeof(sz5), &plis->arg5);
1063       *output = StringPrintf("NPP_Write(%#08lx, %#08lx, %li, %li, %s))",dw1,dw2,dw3,dw4,sz5);
1064       break;
1065     }
1066     case action_npp_print:
1067       *output = StringPrintf("NPP_Print(%#08lx, %#08lx)", dw1, dw2);
1068       break;
1069     case action_npp_handle_event:
1070     {
1071       NPEvent *event = (NPEvent*)dw2;
1072       *output = StringPrintf("NPP_HandleEvent(%#08lx, %#08lx {event=%d, wParam=%#08lx lParam=%#08lx)", dw1,dw2,event->event, event->wParam, event->lParam);
1073       break;
1074     }
1075     case action_npp_url_notify:
1076     {
1077       FormatPCHARArgument(sz2, sizeof(sz2), &plis->arg2);
1078       *output = StringPrintf("NPP_URLNotify(%#08lx, %s, %s, %#08lx)", dw1,sz2,FormatNPAPIReason((int)dw3),dw4);
1079       break;
1080     }
1081     case action_npp_get_java_class:
1082       *output = StringPrintf("NPP_GetJavaClass()");
1083       break;
1084     case action_npp_get_value:
1085       *output = StringPrintf("NPP_GetValue(%#08lx, %s, %#08lx)", dw1,FormatNPPVariable((NPPVariable)dw2),dw3);
1086       break;
1087     case action_npp_set_value:
1088       *output = StringPrintf("NPP_SetValue(%#08lx, %s, %#08lx)", dw1,FormatNPNVariable((NPNVariable)dw2),dw3);
1089       break;
1090 
1091     default:
1092       *output = StringPrintf("Unknown action");
1093       break;
1094   }
1095   *output += szEOL;
1096   *output += szEOI;
1097 }
1098