summaryrefslogtreecommitdiff
path: root/src/lib/evas/cserve2/evas_cs2_client.c
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2013-10-11 14:31:18 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2013-10-28 15:47:16 +0900
commitffa27c70825161606a06cda017d2a82c50cfb34f (patch)
tree2644920cf9030c46a475a822ddf659a064bc31ae /src/lib/evas/cserve2/evas_cs2_client.c
parent745b4d4acc64432b5b531054b94592bee6d55340 (diff)
evas/cserve2: prevent unwanted remap of strings table
In the client, string_get() can cause a remapping of the strings index & mempool. This means that all pointers to string data are invalid past that call. Solution: add a safe_get() function that prevents remap during search. It might prove faster also, but will return NULL more often.
Diffstat (limited to '')
-rw-r--r--src/lib/evas/cserve2/evas_cs2_client.c63
1 files changed, 36 insertions, 27 deletions
diff --git a/src/lib/evas/cserve2/evas_cs2_client.c b/src/lib/evas/cserve2/evas_cs2_client.c
index 6fc1a4a112..df3573f6ef 100644
--- a/src/lib/evas/cserve2/evas_cs2_client.c
+++ b/src/lib/evas/cserve2/evas_cs2_client.c
@@ -74,9 +74,11 @@ static Eina_Hash *_file_entries = NULL;
74// Shared index table 74// Shared index table
75static Index_Table _index; 75static Index_Table _index;
76static const char *_shared_string_get(int id); 76static const char *_shared_string_get(int id);
77static const char *_shared_string_safe_get(int id); // Do not allow remap during search
78static Eina_Bool _string_index_refresh(void);
77static int _server_index_list_set(Msg_Base *data, int size); 79static int _server_index_list_set(Msg_Base *data, int size);
78static const File_Data *_shared_file_data_get_by_id(unsigned int id); 80static const File_Data *_shared_file_data_get_by_id(unsigned int id);
79static const Shm_Object *_shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id); 81static const Shm_Object *_shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id, Eina_Bool safe);
80static const File_Data *_shared_image_entry_file_data_find(Image_Entry *ie); 82static const File_Data *_shared_image_entry_file_data_find(Image_Entry *ie);
81static const Image_Data *_shared_image_entry_image_data_find(Image_Entry *ie); 83static const Image_Data *_shared_image_entry_image_data_find(Image_Entry *ie);
82static const Font_Data *_shared_font_entry_data_find(Font_Entry *fe); 84static const Font_Data *_shared_font_entry_data_find(Font_Entry *fe);
@@ -1788,6 +1790,7 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints)
1788 int cnt = 0; 1790 int cnt = 0;
1789 const char *idxpath = NULL, *datapath = NULL; 1791 const char *idxpath = NULL, *datapath = NULL;
1790 1792
1793 _string_index_refresh();
1791 if (!fe->map) 1794 if (!fe->map)
1792 { 1795 {
1793 const Font_Data *fd; 1796 const Font_Data *fd;
@@ -1795,8 +1798,8 @@ _font_entry_glyph_map_rebuild_check(Font_Entry *fe, Font_Hint_Flags hints)
1795 fd = _shared_font_entry_data_find(fe); 1798 fd = _shared_font_entry_data_find(fe);
1796 if (!fd) return -1; 1799 if (!fd) return -1;
1797 1800
1798 idxpath = _shared_string_get(fd->glyph_index_shm); 1801 idxpath = _shared_string_safe_get(fd->glyph_index_shm);
1799 datapath = _shared_string_get(fd->mempool_shm); 1802 datapath = _shared_string_safe_get(fd->mempool_shm);
1800 if (!idxpath || !datapath) return -1; 1803 if (!idxpath || !datapath) return -1;
1801 1804
1802 fe->map =_glyph_map_open(fe, idxpath, datapath); 1805 fe->map =_glyph_map_open(fe, idxpath, datapath);
@@ -2527,7 +2530,7 @@ _server_index_list_set(Msg_Base *data, int size)
2527 2530
2528// FIXME: (almost) copy & paste from evas_cserve2_cache.c 2531// FIXME: (almost) copy & paste from evas_cserve2_cache.c
2529static const char * 2532static const char *
2530_shared_string_get(int id) 2533_shared_string_internal_get(int id, Eina_Bool safe)
2531{ 2534{
2532 Index_Entry *ie; 2535 Index_Entry *ie;
2533 2536
@@ -2538,19 +2541,20 @@ _shared_string_get(int id)
2538 } 2541 }
2539 2542
2540 ie = (Index_Entry *) 2543 ie = (Index_Entry *)
2541 _shared_index_item_get_by_id(&_index.strings_index, sizeof(*ie), id); 2544 _shared_index_item_get_by_id(&_index.strings_index, sizeof(*ie), id, safe);
2542 if (!ie) return NULL; 2545 if (!ie) return NULL;
2543 if (ie->offset < 0) return NULL; 2546 if (ie->offset < 0) return NULL;
2544 if (!ie->refcount) return NULL; 2547 if (!ie->refcount) return NULL;
2545 if (ie->offset + ie->length > _index.strings_entries.size) 2548 if (ie->offset + ie->length > _index.strings_entries.size)
2546 { 2549 {
2550 if (safe) return NULL;
2547 if (eina_file_refresh(_index.strings_entries.f) 2551 if (eina_file_refresh(_index.strings_entries.f)
2548 || (_index.strings_entries.size != (int) eina_file_size_get(_index.strings_entries.f))) 2552 || (_index.strings_entries.size != (int) eina_file_size_get(_index.strings_entries.f)))
2549 { 2553 {
2550 DBG("String entries size has changed from %d to %d", 2554 DBG("String entries size has changed from %d to %d",
2551 _index.strings_entries.size, (int) eina_file_size_get(_index.strings_entries.f)); 2555 _index.strings_entries.size, (int) eina_file_size_get(_index.strings_entries.f));
2552 if (_string_index_refresh()) 2556 if (_string_index_refresh())
2553 return _shared_string_get(id); 2557 return _shared_string_internal_get(id, EINA_FALSE);
2554 } 2558 }
2555 return NULL; 2559 return NULL;
2556 } 2560 }
@@ -2558,6 +2562,18 @@ _shared_string_get(int id)
2558 return _index.strings_entries.data + ie->offset; 2562 return _index.strings_entries.data + ie->offset;
2559} 2563}
2560 2564
2565static const char *
2566_shared_string_safe_get(int id)
2567{
2568 return _shared_string_internal_get(id, EINA_TRUE);
2569}
2570
2571static const char *
2572_shared_string_get(int id)
2573{
2574 return _shared_string_internal_get(id, EINA_FALSE);
2575}
2576
2561#define SHARED_INDEX_CHECK(si, typ) \ 2577#define SHARED_INDEX_CHECK(si, typ) \
2562 do { if (!_shared_index_remap_check(&(si), sizeof(typ))) { \ 2578 do { if (!_shared_index_remap_check(&(si), sizeof(typ))) { \
2563 CRIT("Failed to remap index"); return NULL; } } while (0) 2579 CRIT("Failed to remap index"); return NULL; } } while (0)
@@ -2597,6 +2613,7 @@ _shared_image_entry_file_data_find(Image_Entry *ie)
2597 return fdata; 2613 return fdata;
2598 2614
2599 // Scan shared index 2615 // Scan shared index
2616 _string_index_refresh();
2600 for (k = _index.files.last_entry_in_hash; 2617 for (k = _index.files.last_entry_in_hash;
2601 k < _index.files.count && k < _index.files.header->emptyidx; k++) 2618 k < _index.files.count && k < _index.files.header->emptyidx; k++)
2602 { 2619 {
@@ -2609,8 +2626,8 @@ _shared_image_entry_file_data_find(Image_Entry *ie)
2609 if (!fd->id) break; 2626 if (!fd->id) break;
2610 if (!fd->refcount) continue; 2627 if (!fd->refcount) continue;
2611 2628
2612 key = _shared_string_get(fd->key); 2629 key = _shared_string_safe_get(fd->key);
2613 file = _shared_string_get(fd->path); 2630 file = _shared_string_safe_get(fd->path);
2614 if (!file) 2631 if (!file)
2615 { 2632 {
2616 ERR("Could not find filename for file %d: path id: %d", 2633 ERR("Could not find filename for file %d: path id: %d",
@@ -2619,11 +2636,6 @@ _shared_image_entry_file_data_find(Image_Entry *ie)
2619 continue; 2636 continue;
2620 } 2637 }
2621 2638
2622 // Note: The strings base pointer may change if the index grows
2623 if ((key < _index.strings_entries.data) ||
2624 (key > _index.strings_entries.data + _index.strings_entries.size))
2625 key = _shared_string_get(fd->key);
2626
2627 lo.region.x = fd->lo.region.x; 2639 lo.region.x = fd->lo.region.x;
2628 lo.region.y = fd->lo.region.y; 2640 lo.region.y = fd->lo.region.y;
2629 lo.region.w = fd->lo.region.w; 2641 lo.region.w = fd->lo.region.w;
@@ -2650,7 +2662,8 @@ _shared_image_entry_file_data_find(Image_Entry *ie)
2650} 2662}
2651 2663
2652static const Shm_Object * 2664static const Shm_Object *
2653_shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id) 2665_shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id,
2666 Eina_Bool safe)
2654{ 2667{
2655 const Shm_Object *obj; 2668 const Shm_Object *obj;
2656 const char *base; 2669 const char *base;
@@ -2665,7 +2678,7 @@ _shared_index_item_get_by_id(Shared_Index *si, int elemsize, unsigned int id)
2665 2678
2666 if (high > si->count) 2679 if (high > si->count)
2667 { 2680 {
2668 if (eina_file_refresh(si->f)) 2681 if ((!safe) && eina_file_refresh(si->f))
2669 { 2682 {
2670 WRN("Refreshing indexes."); 2683 WRN("Refreshing indexes.");
2671 _string_index_refresh(); 2684 _string_index_refresh();
@@ -2717,7 +2730,7 @@ static const File_Data *
2717_shared_file_data_get_by_id(unsigned int id) 2730_shared_file_data_get_by_id(unsigned int id)
2718{ 2731{
2719 return (const File_Data *) 2732 return (const File_Data *)
2720 _shared_index_item_get_by_id(&_index.files, sizeof(File_Data), id); 2733 _shared_index_item_get_by_id(&_index.files, sizeof(File_Data), id, EINA_FALSE);
2721} 2734}
2722 2735
2723static inline Eina_Bool 2736static inline Eina_Bool
@@ -2932,6 +2945,7 @@ _shared_image_entry_image_data_find(Image_Entry *ie)
2932 2945
2933 // Linear search in non-hashed entries. O(n) 2946 // Linear search in non-hashed entries. O(n)
2934 DBG("Looking for loaded image with file id %d", file_id); 2947 DBG("Looking for loaded image with file id %d", file_id);
2948 _string_index_refresh();
2935 for (k = _index.images.last_entry_in_hash; k < _index.images.count; k++) 2949 for (k = _index.images.last_entry_in_hash; k < _index.images.count; k++)
2936 { 2950 {
2937 const char *file, *key; 2951 const char *file, *key;
@@ -2953,8 +2967,8 @@ _shared_image_entry_image_data_find(Image_Entry *ie)
2953 continue; 2967 continue;
2954 } 2968 }
2955 2969
2956 key = _shared_string_get(fd->key); 2970 key = _shared_string_safe_get(fd->key);
2957 file = _shared_string_get(fd->path); 2971 file = _shared_string_safe_get(fd->path);
2958 if (!file) 2972 if (!file)
2959 { 2973 {
2960 ERR("No filename for file %d", fd->id); 2974 ERR("No filename for file %d", fd->id);
@@ -2962,11 +2976,6 @@ _shared_image_entry_image_data_find(Image_Entry *ie)
2962 continue; 2976 continue;
2963 } 2977 }
2964 2978
2965 // Note: The strings base pointer may change if the index grows
2966 if ((key < _index.strings_entries.data) ||
2967 (key > _index.strings_entries.data + _index.strings_entries.size))
2968 key = _shared_string_get(fd->key);
2969
2970 keylen = key ? strlen(key) : 0; 2979 keylen = key ? strlen(key) : 0;
2971 filelen = strlen(file); 2980 filelen = strlen(file);
2972 2981
@@ -2996,7 +3005,7 @@ found:
2996 return NULL; 3005 return NULL;
2997 } 3006 }
2998 3007
2999 shmpath = _shared_string_get(idata->shm_id); 3008 shmpath = _shared_string_safe_get(idata->shm_id);
3000 if (!shmpath) 3009 if (!shmpath)
3001 { 3010 {
3002 ERR("Found image but it is not loaded yet: %d (doload %d)", 3011 ERR("Found image but it is not loaded yet: %d (doload %d)",
@@ -3012,7 +3021,7 @@ static const Font_Data *
3012_shared_font_entry_data_get_by_id(int id) 3021_shared_font_entry_data_get_by_id(int id)
3013{ 3022{
3014 return (Font_Data *) 3023 return (Font_Data *)
3015 _shared_index_item_get_by_id(&_index.fonts, sizeof(Font_Data), id); 3024 _shared_index_item_get_by_id(&_index.fonts, sizeof(Font_Data), id, EINA_FALSE);
3016} 3025}
3017 3026
3018static const Font_Data * 3027static const Font_Data *
@@ -3051,8 +3060,8 @@ _shared_font_entry_data_find(Font_Entry *fe)
3051 if (!cur->id) return NULL; 3060 if (!cur->id) return NULL;
3052 if (!cur->refcount) continue; 3061 if (!cur->refcount) continue;
3053 3062
3054 name = _shared_string_get(cur->name); 3063 name = _shared_string_safe_get(cur->name);
3055 source = _shared_string_get(cur->file); 3064 source = _shared_string_safe_get(cur->file);
3056 snprintf(hkey, PATH_MAX, "%s:%s/%u:%u:%u", source, name, 3065 snprintf(hkey, PATH_MAX, "%s:%s/%u:%u:%u", source, name,
3057 cur->size, cur->dpi, cur->rend_flags); 3066 cur->size, cur->dpi, cur->rend_flags);
3058 3067