{"action":"closed","issue":{"url":"https://api.github.com/repos/DynamoRIO/drmemory/issues/1807","labels_url":"https://api.github.com/repos/DynamoRIO/drmemory/issues/1807/labels{/name}","comments_url":"https://api.github.com/repos/DynamoRIO/drmemory/issues/1807/comments","events_url":"https://api.github.com/repos/DynamoRIO/drmemory/issues/1807/events","html_url":"https://github.com/DynamoRIO/drmemory/issues/1807","id":113922065,"number":1807,"title":"buffer overflow in replace_wcsstr and replace_strstr","user":{"login":"zhaoqin","id":1645580,"avatar_url":"https://avatars.githubusercontent.com/u/1645580?v=3","gravatar_id":"","url":"https://api.github.com/users/zhaoqin","html_url":"https://github.com/zhaoqin","followers_url":"https://api.github.com/users/zhaoqin/followers","following_url":"https://api.github.com/users/zhaoqin/following{/other_user}","gists_url":"https://api.github.com/users/zhaoqin/gists{/gist_id}","starred_url":"https://api.github.com/users/zhaoqin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zhaoqin/subscriptions","organizations_url":"https://api.github.com/users/zhaoqin/orgs","repos_url":"https://api.github.com/users/zhaoqin/repos","events_url":"https://api.github.com/users/zhaoqin/events{/privacy}","received_events_url":"https://api.github.com/users/zhaoqin/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/DynamoRIO/drmemory/labels/Status-Invalid","name":"Status-Invalid","color":"FFFFFF"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-10-28T21:07:19Z","updated_at":"2015-10-28T21:10:27Z","closed_at":"2015-10-28T21:10:27Z","body":"```\r\nIN_REPLACE_SECTION char *\r\nreplace_strstr(const char *haystack, const char *needle)\r\n{\r\n    register const char *hs = haystack;\r\n    register const char *n = needle;\r\n    /* empty needle should return haystack */\r\n    if (*n == '\\0')\r\n        return (char *) haystack;\r\n    while (*hs != '\\0') {\r\n        if (*hs != *n && n > needle) {\r\n            hs -= n - 1 - needle; /* backtrack */\r\n            n = needle;\r\n        }\r\n        if (*hs == *n) {\r\n            n++;\r\n            if (*n == '\\0')\r\n                return (char *) (hs - (n - 1 - needle));\r\n        }\r\n        hs++;\r\n    }\r\n    return NULL;\r\n}\r\n```\r\nFor case `*hs != *n`, `hs -= n - 1 - needle`, and then `hs++` at end of the loop, so hs may advance twice.\r\ntest example:\r\n```\r\n    char *p = new char[3];\r\n    strcpy(p, \"xxx\");\r\n    ASSERT_STREQ(strstr(p, \"xxxy\"), (char *)NULL);\r\n    delete [] p;\r\n```"}}