Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: gcc resize_and_overwrite 導致髒數據的問題 #509

Closed
hoskylucky opened this issue Jan 30, 2024 · 21 comments · Fixed by #512
Closed

bug: gcc resize_and_overwrite 導致髒數據的問題 #509

hoskylucky opened this issue Jan 30, 2024 · 21 comments · Fixed by #512

Comments

@hoskylucky
Copy link

hi,我在使用cinatra的時候會遇到一些問題,在http read request的時候body會有髒數據,檢查了一下發現發生問題的地方出在details::resize中,gcc的resize_and_overwrite貌似會返回capacity,在stackoverflow中有討論,并且gcc bugzilla也有提到。
我使用的環境爲ubuntu 22.04 / gcc 13.2/ cinatra 0.8.3
感謝。

@qicosmos
Copy link
Owner

谢谢报告,稍晚看一下。

@poor-circle
Copy link
Contributor

poor-circle commented Jan 30, 2024

hi,我在使用cinatra的時候會遇到一些問題,在http read request的時候body會有髒數據,檢查了一下發現發生問題的地方出在details::resize中,gcc的resize_and_overwrite貌似會返回capacity,在stackoverflow中有討論,并且gcc bugzilla也有提到。 我使用的環境爲ubuntu 22.04 / gcc 13.2/ cinatra 0.8.3 感謝。

我们现在没有用到这个函数提供的sz啊

@qicosmos
Copy link
Owner

有测试代码?需要复现查问题。

@hoskylucky
Copy link
Author

cinatra這裏用到了resize,裏面是用std::base_string::resize_and_overwrite進行string的内存擴展(std=c++23),作者的blog也有提到,測試代碼

@poor-circle
Copy link
Contributor

问题是我们不会用到返回值

@poor-circle
Copy link
Contributor

所以问题出在别的地方。
你能否提供一段测试代码?

@hoskylucky
Copy link
Author

這時候的size預期設置爲25,但是實際上設置成了30,在後面使用memcpy沒有#0,導致多出來的内存可能被外面讀成髒數據。

@poor-circle
Copy link
Contributor

這時候的size預期設置爲25,但是實際上設置成了30,在後面使用memcpy沒有#0,導致多出來的内存可能被外面讀成髒數據。

實際上設置成了30-> 指的是string的容量?

@hoskylucky
Copy link
Author

hoskylucky commented Jan 30, 2024

是的,string.size()是大於body_len的,但是後面沒有/0,所以外面可能讀出髒數據

@poor-circle
Copy link
Contributor

poor-circle commented Jan 30, 2024

是的,string.size()是大於body_len的,但是後面沒有/0,所以外面可能讀出髒數據

你指的是string::size()大于body_len还是string::capacity()大于body_len

@poor-circle
Copy link
Contributor

poor-circle commented Jan 30, 2024

這時候的size預期設置爲25,但是實際上設置成了30,在後面使用memcpy沒有#0,導致多出來的内存可能被外面讀成髒數據。

我理解,代码期望的行为可能是,

1.body_len==25, size()==25, capacity()==30,然后data[25]=='\0',后面跟4个字节的脏数据。这是正常的。

如果出问题,可能是:
2. body_len==25, size()==25, capacity()==30,但是data[25]是脏数据而不是\0
3. body_len==25, size()==30, capacity()==30.
在你的测试代码中是哪种情况呢?

@hoskylucky
Copy link
Author

這時候的size預期設置爲25,但是實際上設置成了30,在後面使用memcpy沒有#0,導致多出來的内存可能被外面讀成髒數據。

我理解,代码期望的行为可能是,size()==25, capacity()==30,然后data[25]=='\0',后面跟4个字节的脏数据。这是正常的。

是的這個行爲是正常的,但是在使用memcpy的時候僅拷貝了body_len爲25的字節,後面沒有\0,就變成了5個字節的髒數據。
現在是bodylen是25,size()是30,capacity()是30,使用memcpy拷貝了25字節,應該是拷貝25+1個字節,把\0算上。
不知道我是否描述清楚了。

@poor-circle
Copy link
Contributor

這時候的size預期設置爲25,但是實際上設置成了30,在後面使用memcpy沒有#0,導致多出來的内存可能被外面讀成髒數據。

我理解,代码期望的行为可能是,size()==25, capacity()==30,然后data[25]=='\0',后面跟4个字节的脏数据。这是正常的。

是的這個行爲是正常的,但是在使用memcpy的時候僅拷貝了body_len爲25的字節,後面沒有\0,就變成了5個字節的髒數據。 現在是bodylen是25,size()是30,capacity()是30,使用memcpy拷貝了25字節,應該是拷貝25+1個字節,把\0算上。 不知道我是否描述清楚了。

@qicosmos

@poor-circle
Copy link
Contributor

這時候的size預期設置爲25,但是實際上設置成了30,在後面使用memcpy沒有#0,導致多出來的内存可能被外面讀成髒數據。

我理解,代码期望的行为可能是,size()==25, capacity()==30,然后data[25]=='\0',后面跟4个字节的脏数据。这是正常的。

是的這個行爲是正常的,但是在使用memcpy的時候僅拷貝了body_len爲25的字節,後面沒有\0,就變成了5個字節的髒數據。 現在是bodylen是25,size()是30,capacity()是30,使用memcpy拷貝了25字節,應該是拷貝25+1個字節,把\0算上。 不知道我是否描述清楚了。

這時候的size預期設置爲25,但是實際上設置成了30,在後面使用memcpy沒有#0,導致多出來的内存可能被外面讀成髒數據。

我理解,代码期望的行为可能是,size()==25, capacity()==30,然后data[25]=='\0',后面跟4个字节的脏数据。这是正常的。

是的這個行爲是正常的,但是在使用memcpy的時候僅拷貝了body_len爲25的字節,後面沒有\0,就變成了5個字節的髒數據。 現在是bodylen是25,size()是30,capacity()是30,使用memcpy拷貝了25字節,應該是拷貝25+1個字節,把\0算上。 不知道我是否描述清楚了。

所以是这三种情况的哪一种呢?

@poor-circle
Copy link
Contributor

1.body_len==25, size()==25, capacity()==30,然后data[25]=='\0',后面跟4个字节的脏数据。这是正常的。
2. body_len==25, size()==25, capacity()==30,但是data[25]是脏数据而不是\0
3. body_len==25, size()==30, capacity()==30.

@hoskylucky
Copy link
Author

1.body_len==25, size()==25, capacity()==30,然后data[25]=='\0',后面跟4个字节的脏数据。这是正常的。 2. body_len==25, size()==25, capacity()==30,但是data[25]是脏数据而不是\0 3. body_len==25, size()==30, capacity()==30.

  1. body_len==25, size()==30, capacity()==30, 但是data[25]是脏数据而不是\0

@qicosmos
Copy link
Owner

能给个测试cinara的代码吗,先不纠结resize这里,我希望有个实际的例子能复现问题。@hoskylucky

@poor-circle
Copy link
Contributor

我懂了,等下会提一个pr fix

@qicosmos qicosmos mentioned this issue Jan 30, 2024
Merged
@poor-circle
Copy link
Contributor

https://godbolt.org/z/EefoE751z

我理解问题以及修复方案是这样的

@qicosmos
Copy link
Owner

用这个pr #512
验证一下
@hoskylucky

@hoskylucky
Copy link
Author

這樣就沒問題了,感謝。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants