boostorg / boostorg/gil

kth_channel_view fails when used with virtual views (Trac 9020)

未关闭
#151 2 条评论 0 个 reaction 已指派 3 人 已被 @chhenning 认领 在 GitHub 查看
status/need-feedback
主要语言
C++
星标
199
派生
171
平均合并
1 天 14 小时
30 天内合并 PR
10

描述

Moved from https://svn.boost.org/trac10/ticket/9020 description:

> Given an image_view with a `virtual_2d_locator` that returns a `planar_pixel_reference`, `kth_channel_view` produces a `kth_channel_deref_fn` with an incorrect `result_type` which may result an invalid pointer dereference.
>
> For example, consider a `virtual_2d_locator` instantiated with a dereference functor that returns a `planar_pixel_reference`
>
> An image_view instantiated with such a locator will have a reference type of `planar_pixel_reference`. Now suppose this image_view is passed to `kth_channel_view()`. This results in the instantiation of a `kth_channel_deref_fn` with a result_type of `pixel&` however, the deref functor will initialize this result_type with a `pixel&`.
>
> `detail::kth_channel_deref_fn` needs to ensure the channel type of its `result_type` is not a reference type.

Patch:

```
--- image_view_factory.hpp.orig 2013-08-19 12:20:06.000000000 -0500
+++ image_view_factory.hpp 2013-08-19 13:11:49.000000000 -0500
@@ -479,7 +479,8 @@
BOOST_STATIC_CONSTANT(bool, is_mutable=pixel_is_reference::value && pixel_reference_is_mutable::value);
private:
typedef typename remove_reference::type src_pixel_t;
- typedef typename kth_element_type::type channel_t;
+ typedef typename kth_element_type::type channel_ref_t;
+ typedef typename remove_reference::type channel_t;
typedef typename src_pixel_t::const_reference const_ref_t;
typedef typename pixel_reference_type::type ref_t;
public:
```

Example program illustrating the issue:

```
#include
#include
using namespace boost;
using namespace gil;

//
// Do-nothing dereference adaptor
//
template
struct deref_fn {
BOOST_STATIC_CONSTANT(bool, is_mutable=false);
typedef deref_fn const_t;
typedef typename View::value_type value_type;
typedef typename View::reference reference;
typedef typename View::point_t argument_type;
typedef reference result_type;

deref_fn() {;}
deref_fn(const View& v) : mView(v) { ; }
result_type operator()(const argument_type& p) const {
return mView(p);
}

View mView;
};

typedef rgb8_planar_image_t image_t;
typedef image_t::view_t view_t;
typedef deref_fn fn_t;
typedef virtual_2d_locator loc_t;
typedef image_view virt_view_t;
typedef kth_channel_view_type<0, virt_view_t>::type chan0_view_t;

int main(int argc, char **argv) {
image_t img(4,4,rgb8_pixel_t(1,2,3),0);
view_t v(view(img));

fn_t fn(v);
loc_t loc(view_t::point_t(0,0), view_t::point_t(1,1), fn);
virt_view_t virtView(v.dimensions(), loc);

//
// Here detail::kth_channel_deref_fn is instantiated with
// SrcP = 'planar_pixel_reference'. The
// kth_channel_deref_fn then declares its result_type (and thereby
// the chan0_view_t:reference) to be a
// 'pixel&'
//
chan0_view_t chan0View(kth_channel_view<0,virt_view_t>(virtView));

assert((is_same& >::value));

//
// This will typically cause a bus error because the result_type
// of the deref adaptor is a 'pixel&'
// which gets initialized in the deref function by a
// 'pixel&'
//
assert(chan0View(0,0) == gray8_pixel_t(1));
return 0;
}
```

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。