1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/shared_impl/ppb_instance_shared.h"
6
7#include <string>
8
9#include "base/debug/trace_event.h"
10#include "base/threading/platform_thread.h"
11#include "ppapi/c/pp_errors.h"
12#include "ppapi/c/ppb_input_event.h"
13#include "ppapi/shared_impl/ppapi_globals.h"
14#include "ppapi/shared_impl/ppb_image_data_shared.h"
15#include "ppapi/shared_impl/var.h"
16#include "ppapi/thunk/enter.h"
17#include "ppapi/thunk/ppb_image_data_api.h"
18
19namespace ppapi {
20
21// static
22const int PPB_Instance_Shared::kExtraCharsForTextInput = 100;
23
24PPB_Instance_Shared::~PPB_Instance_Shared() {}
25
26void PPB_Instance_Shared::Log(PP_Instance instance,
27                              PP_LogLevel level,
28                              PP_Var value) {
29  LogWithSource(instance, level, PP_MakeUndefined(), value);
30}
31
32void PPB_Instance_Shared::LogWithSource(PP_Instance instance,
33                                        PP_LogLevel level,
34                                        PP_Var source,
35                                        PP_Var value) {
36  // The source defaults to empty if it's not a string. The PpapiGlobals
37  // implementation will convert the empty string to the module name if
38  // possible.
39  std::string source_str;
40  if (source.type == PP_VARTYPE_STRING)
41    source_str = Var::PPVarToLogString(source);
42  std::string value_str = Var::PPVarToLogString(value);
43  PpapiGlobals::Get()->LogWithSource(instance, level, source_str, value_str);
44}
45
46int32_t PPB_Instance_Shared::ValidateRequestInputEvents(
47    bool is_filtering,
48    uint32_t event_classes) {
49  // See if any bits are set we don't know about.
50  if (event_classes & ~static_cast<uint32_t>(PP_INPUTEVENT_CLASS_MOUSE |
51                                             PP_INPUTEVENT_CLASS_KEYBOARD |
52                                             PP_INPUTEVENT_CLASS_WHEEL |
53                                             PP_INPUTEVENT_CLASS_TOUCH |
54                                             PP_INPUTEVENT_CLASS_IME))
55    return PP_ERROR_NOTSUPPORTED;
56
57  // Everything else is valid.
58  return PP_OK;
59}
60
61bool PPB_Instance_Shared::ValidateSetCursorParams(PP_MouseCursor_Type type,
62                                                  PP_Resource image,
63                                                  const PP_Point* hot_spot) {
64  if (static_cast<int>(type) < static_cast<int>(PP_MOUSECURSOR_TYPE_CUSTOM) ||
65      static_cast<int>(type) > static_cast<int>(PP_MOUSECURSOR_TYPE_GRABBING))
66    return false;  // Cursor type out of range.
67  if (type != PP_MOUSECURSOR_TYPE_CUSTOM) {
68    // The image must not be specified if the type isn't custom. However, we
69    // don't require that the hot spot be null since the C++ wrappers and proxy
70    // pass the point by reference and it will normally be specified.
71    return image == 0;
72  }
73
74  if (!hot_spot)
75    return false;  // Hot spot must be specified for custom cursor.
76
77  thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter(image, true);
78  if (enter.failed())
79    return false;  // Invalid image resource.
80
81  // Validate the image size. A giant cursor can arbitrarily overwrite parts
82  // of the screen resulting in potential spoofing attacks. So we force the
83  // cursor to be a reasonably-sized image.
84  PP_ImageDataDesc desc;
85  if (!PP_ToBool(enter.object()->Describe(&desc)))
86    return false;
87  if (desc.size.width > 32 || desc.size.height > 32)
88    return false;
89
90  // Validate image format.
91  if (desc.format != PPB_ImageData_Shared::GetNativeImageDataFormat())
92    return false;
93
94  // Validate the hot spot location.
95  if (hot_spot->x < 0 || hot_spot->x >= desc.size.width || hot_spot->y < 0 ||
96      hot_spot->y >= desc.size.height)
97    return false;
98  return true;
99}
100
101}  // namespace ppapi
102