• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/proxy/serialized_flash_menu.h"
6 
7 #include "ipc/ipc_message.h"
8 #include "ppapi/c/private/ppb_flash_menu.h"
9 #include "ppapi/proxy/ppapi_param_traits.h"
10 
11 namespace ppapi {
12 namespace proxy {
13 
14 namespace {
15 // Maximum depth of submenus allowed (e.g., 1 indicates that submenus are
16 // allowed, but not sub-submenus).
17 const int kMaxMenuDepth = 2;
18 const uint32_t kMaxMenuEntries = 1000;
19 
20 bool CheckMenu(int depth, const PP_Flash_Menu* menu);
21 void FreeMenu(const PP_Flash_Menu* menu);
22 void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu);
23 PP_Flash_Menu* ReadMenu(int depth, const IPC::Message* m, PickleIterator* iter);
24 
CheckMenuItem(int depth,const PP_Flash_MenuItem * item)25 bool CheckMenuItem(int depth, const PP_Flash_MenuItem* item) {
26   if (item->type == PP_FLASH_MENUITEM_TYPE_SUBMENU)
27     return CheckMenu(depth, item->submenu);
28   return true;
29 }
30 
CheckMenu(int depth,const PP_Flash_Menu * menu)31 bool CheckMenu(int depth, const PP_Flash_Menu* menu) {
32   if (depth > kMaxMenuDepth || !menu)
33     return false;
34   ++depth;
35 
36   if (menu->count && !menu->items)
37     return false;
38 
39   for (uint32_t i = 0; i < menu->count; ++i) {
40     if (!CheckMenuItem(depth, menu->items + i))
41       return false;
42   }
43   return true;
44 }
45 
WriteMenuItem(IPC::Message * m,const PP_Flash_MenuItem * menu_item)46 void WriteMenuItem(IPC::Message* m, const PP_Flash_MenuItem* menu_item) {
47   PP_Flash_MenuItem_Type type = menu_item->type;
48   m->WriteUInt32(type);
49   m->WriteString(menu_item->name ? menu_item->name : "");
50   m->WriteInt(menu_item->id);
51   IPC::ParamTraits<PP_Bool>::Write(m, menu_item->enabled);
52   IPC::ParamTraits<PP_Bool>::Write(m, menu_item->checked);
53   if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU)
54     WriteMenu(m, menu_item->submenu);
55 }
56 
WriteMenu(IPC::Message * m,const PP_Flash_Menu * menu)57 void WriteMenu(IPC::Message* m, const PP_Flash_Menu* menu) {
58   m->WriteUInt32(menu->count);
59   for (uint32_t i = 0; i < menu->count; ++i)
60     WriteMenuItem(m, menu->items + i);
61 }
62 
FreeMenuItem(const PP_Flash_MenuItem * menu_item)63 void FreeMenuItem(const PP_Flash_MenuItem* menu_item) {
64   if (menu_item->name)
65     delete [] menu_item->name;
66   if (menu_item->submenu)
67     FreeMenu(menu_item->submenu);
68 }
69 
FreeMenu(const PP_Flash_Menu * menu)70 void FreeMenu(const PP_Flash_Menu* menu) {
71   if (menu->items) {
72     for (uint32_t i = 0; i < menu->count; ++i)
73       FreeMenuItem(menu->items + i);
74     delete [] menu->items;
75   }
76   delete menu;
77 }
78 
ReadMenuItem(int depth,const IPC::Message * m,PickleIterator * iter,PP_Flash_MenuItem * menu_item)79 bool ReadMenuItem(int depth,
80                   const IPC::Message* m,
81                   PickleIterator* iter,
82                   PP_Flash_MenuItem* menu_item) {
83   uint32_t type;
84   if (!m->ReadUInt32(iter, &type))
85     return false;
86   if (type > PP_FLASH_MENUITEM_TYPE_SUBMENU)
87     return false;
88   menu_item->type = static_cast<PP_Flash_MenuItem_Type>(type);
89   std::string name;
90   if (!m->ReadString(iter, &name))
91     return false;
92   menu_item->name = new char[name.size() + 1];
93   std::copy(name.begin(), name.end(), menu_item->name);
94   menu_item->name[name.size()] = 0;
95   if (!m->ReadInt(iter, &menu_item->id))
96     return false;
97   if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->enabled))
98     return false;
99   if (!IPC::ParamTraits<PP_Bool>::Read(m, iter, &menu_item->checked))
100     return false;
101   if (type == PP_FLASH_MENUITEM_TYPE_SUBMENU) {
102     menu_item->submenu = ReadMenu(depth, m, iter);
103     if (!menu_item->submenu)
104       return false;
105   }
106   return true;
107 }
108 
ReadMenu(int depth,const IPC::Message * m,PickleIterator * iter)109 PP_Flash_Menu* ReadMenu(int depth,
110                         const IPC::Message* m,
111                         PickleIterator* iter) {
112   if (depth > kMaxMenuDepth)
113     return NULL;
114   ++depth;
115 
116   PP_Flash_Menu* menu = new PP_Flash_Menu;
117   menu->items = NULL;
118 
119   if (!m->ReadUInt32(iter, &menu->count)) {
120     FreeMenu(menu);
121     return NULL;
122   }
123 
124   if (menu->count == 0)
125     return menu;
126 
127   if (menu->count > kMaxMenuEntries) {
128     FreeMenu(menu);
129     return NULL;
130   }
131 
132   menu->items = new PP_Flash_MenuItem[menu->count];
133   memset(menu->items, 0, sizeof(PP_Flash_MenuItem) * menu->count);
134   for (uint32_t i = 0; i < menu->count; ++i) {
135     if (!ReadMenuItem(depth, m, iter, menu->items + i)) {
136       FreeMenu(menu);
137       return NULL;
138     }
139   }
140   return menu;
141 }
142 
143 }  // anonymous namespace
144 
SerializedFlashMenu()145 SerializedFlashMenu::SerializedFlashMenu()
146     : pp_menu_(NULL),
147       own_menu_(false) {
148 }
149 
~SerializedFlashMenu()150 SerializedFlashMenu::~SerializedFlashMenu() {
151   if (own_menu_)
152     FreeMenu(pp_menu_);
153 }
154 
SetPPMenu(const PP_Flash_Menu * menu)155 bool SerializedFlashMenu::SetPPMenu(const PP_Flash_Menu* menu) {
156   DCHECK(!pp_menu_);
157   if (!CheckMenu(0, menu))
158     return false;
159   pp_menu_ = menu;
160   own_menu_ = false;
161   return true;
162 }
163 
164 
WriteToMessage(IPC::Message * m) const165 void SerializedFlashMenu::WriteToMessage(IPC::Message* m) const {
166   WriteMenu(m, pp_menu_);
167 }
168 
ReadFromMessage(const IPC::Message * m,PickleIterator * iter)169 bool SerializedFlashMenu::ReadFromMessage(const IPC::Message* m,
170                                           PickleIterator* iter) {
171   DCHECK(!pp_menu_);
172   pp_menu_ = ReadMenu(0, m, iter);
173   if (!pp_menu_)
174     return false;
175 
176   own_menu_ = true;
177   return true;
178 }
179 
180 }  // namespace proxy
181 }  // namespace ppapi
182