首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >URL解码函数优化

URL解码函数优化
EN

Code Review用户
提问于 2013-05-13 14:08:05
回答 1查看 1.9K关注 0票数 3

我有下面的模型,我需要一些反馈,说明我如何改进url_decode函数,使它更快,使用更少的内存。有几个要求。我必须使用StringArgStringReturn结构。我还需要完全解码字符串。我知道双重编码的攻击,但是这是用于数据挖掘的,我需要得到完全解码的字符串,因此是while循环。

请看一看函数StringReturn* url_decode(char* line),并建议任何我能做的,以提高速度或减少内存使用。

代码语言:javascript
复制
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <ctype.h>

struct StringArg
{
    int length;
    char* data;
    StringArg(const char* inData)
    {
        length = strlen(inData);
        data = new char[length+1];
        strcpy(data, inData);
    }
};

struct StringReturn
{
    int size;
    char* data;
    StringReturn(int inSize)
    {
        size = inSize;
        data = new char[size+1];
    }
};

StringArg* stringArg(char* line)
{
    return new StringArg(line);
}

StringReturn* stringReturnInfo(int size)
{
    return new StringReturn(size);
}

StringReturn* url_decode(char* line)
{
        StringArg *str;
        str = stringArg(line);

        int lengths = str->length;
        char* urlData = new char[lengths+1];
        char* fmt = new char[4];
        memcpy(urlData, str->data, str->length);
        urlData[lengths] = 0;
        bool bFoundChar = false;

        int j = 0;

        do
        {
                j = 0;
                bFoundChar = false;
                for (int i = 0; i < lengths; i++)
                {
                        char ch = urlData[i];
                        if (ch == '+')
                        {
                                urlData[j++] = ' ';
                        }
                        else if (ch == '%' && i+2 < lengths &&  isxdigit(urlData[i+1]) &&  isxdigit(urlData[i+2]))
                        {
                                bFoundChar = true;
                                fmt = new char[4];

                                fmt[0] = urlData[++i];
                                fmt[1] = urlData[++i];
                                fmt[2] = 0;

                                urlData[j++] = (char)strtol(fmt, NULL, 16);

                        }
                        else {
                                urlData[j++] = ch;
                        }
                }
                lengths = j;
        }while (bFoundChar);

        StringReturn *ret = stringReturnInfo(j);
        ret->size = j;

        memcpy(ret->data, urlData, j);
        delete urlData;
        delete fmt;

        return ret;

}

void test_decode(char* line)
{
    StringReturn *str = url_decode(line);
    printf(str->data);
}

int main(int argc, const char * argv[])
{

    test_decode("bob.com?url=http%3A%2F%2Fsteve.com%3Furl%3Dhttp%253A%252F%252Fjohn.com");

    return 0;
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2013-05-13 18:42:03

这注定要失败:

代码语言:javascript
复制
struct StringArg
{
    int length;
    char* data;
    StringArg(const char* inData)
    {
        length = strlen(inData);
        data = new char[length+1];
        strcpy(data, inData);
    }
};

这只会导致灾难。它不太可能比std::string更有效,并且更有可能导致内存泄漏。

使用std::string,它的工作原理是正确的,并且经过了很大程度的优化,您不能用自己的手编写一个字符串。这是一个过早的优化。

同样:

代码语言:javascript
复制
struct StringReturn
{
    int size;
    char* data;
    StringReturn(int inSize)
    {
        size = inSize;
        data = new char[size+1];
    }
};

不要在周围传递指针:

代码语言:javascript
复制
StringArg* stringArg(char* line)
{
    return new StringArg(line);
}

使用std::unique_ptr封装指针对象,使其能够正确管理内存。如果您做的事情是正确的,结果代码优化为无操作,如果您不正确地做事情,它会节省您的屁股。实际上,我会丢弃您的字符串类并使用std::string。来自返回的复制构造几乎总是被NRVO所忽略,因此比您想象的要高效得多。

又一样

代码语言:javascript
复制
StringReturn* stringReturnInfo(int size)
{
    return new StringReturn(size);
}

手动复制C-字符串是非常痛苦的。使用std::string

代码语言:javascript
复制
    int lengths = str->length;
    char* urlData = new char[lengths+1];
    char* fmt = new char[4];
    memcpy(urlData, str->data, str->length);
    urlData[lengths] = 0;

    // Or you can do:

    std::string urlData = line;

此外,您的代码也不例外安全。

请使用RIAA确保没有泄漏(或者使用std::string已经这样做了)。

在这里可以找到URL的定义:https://www.rfc-editor.org/rfc/rfc3986

假装'+‘是一个空格只在URI的path部分有效,而在URI的查询或片段部分无效,因此扫描整个字符串以获得'+’是不正确的。

我还需要完全解码字符串。我知道双重编码的攻击

该规范不允许双重(或嵌套)编码。如果它解码为另一个'%‘,那么这就是值。你不要试图重新解释这个价值。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/26103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档