`strtol`的实现是什么?

时间:2011-09-17 19:12:30

标签: c

我对此很好奇。 strtol不要求您指定要处理的字节数,因此理论上它可能会被包含一个包含无限数字序列的字符串以供使用,从而导致拒绝服务攻击。当然,通过意识到长时间的精度已经耗尽(实际上不能超过65个二进制数的字符)很容易被挫败,没有必要再读一读。

但是,strtol还需要丢弃尽可能多的空白字符,直到遇到第一个非空白字符。那么即使它对读数字很聪明,也不会被无尽的空白字符串攻击吗?

4 个答案:

答案 0 :(得分:3)

  

但是,strtol还需要丢弃尽可能多的空白字符,直到遇到第一个非空白字符。那么,即使它对读数字很聪明,也不会被无尽的空白字符串攻击吗?

strtol对已经在内存中的字符串起作用时,你必须存储(并从攻击者中读取)一个“无穷无尽”的空白量(或者忘记NUL终止你的字符串)到了strtol。

由于实现可以保持计算有效字符串中可以存在的最大位数,因此您不必像往常一样继续计算。

但是,对于错误的实现,可能会发生DOS攻击,请查看this相关案例(在读取双精度时,这是在java和PHP中,但在C或C ++实现中也会出现相同情况)。

答案 1 :(得分:1)

strtol没有单一的实施方式。我怀疑任何实现都容易受到你所描述的那种攻击的影响;显而易见的实现只是遍历数字序列而不是一次性存储它们。 (请注意,由于前导0 s,数字序列可以任意长。)

如果您想查看实现的代码,可以下载glibc版本here; strtol()位于stdlib/strtol.c

答案 2 :(得分:0)

我的个人实施。我没有使用任何前瞻(访问$(".word").typed({ strings:['aaa','bbb','ccc','ddd'], typeSpeed: 45, backSpeed: 30, backDelay: 5000, // loop loop: true, // null = infinite loopCount: null, }); 或类似的东西),所以理论上你可以将它转换为从流中读取的内容(例如p[1]为字符调用get_long()

getc()

答案 3 :(得分:-1)

如果你想看到strtol,你可以通过加州大学看到这个

/* 
 * strtol.c --
 *
 *  Source code for the "strtol" library procedure.
 *
 * Copyright (c) 1988 The Regents of the University of California.
 * All rights reserved.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 * 
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 */
static const char rcsid[] = "$Header$ SPRITE (Berkeley)";

#include <ctype.h>

extern unsigned long int strtoul(char *string, char **endPtr, int base);

/*
 *----------------------------------------------------------------------
 *
 * strtol --
 *
 *  Convert an ASCII string into an integer.
 *
 * Results:
 *  The return value is the integer equivalent of string.  If endPtr
 *  is non-NULL, then *endPtr is filled in with the character
 *  after the last one that was part of the integer.  If string
 *  doesn't contain a valid integer value, then zero is returned
 *  and *endPtr is set to string.
 *
 * Side effects:
 *  None.
 *
 *----------------------------------------------------------------------
 */

long int
strtol(
    char *string,       /* String of ASCII digits, possibly
                 * preceded by white space.  For bases
                 * greater than 10, either lower- or
                 * upper-case digits may be used.
                 */
    char **endPtr,      /* Where to store address of terminating
                 * character, or NULL. */
    int base            /* Base for conversion.  Must be less
                 * than 37.  If 0, then the base is chosen
                 * from the leading characters of string:
                 * "0x" means hex, "0" means octal, anything
                 * else means decimal.
                 */
)
{
    register char *p;
    int result;

    /*
     * Skip any leading blanks.
     */
    p = string;
    while (isspace(*p)) {
    p += 1;
    }

    /*
     * Check for a sign.
     */
    if (*p == '-') {
    p += 1;
    result = -1*(strtoul(p, endPtr, base));
    } else {
    if (*p == '+') {
        p += 1;
    }
    result = strtoul(p, endPtr, base);
    }
    if ((result == 0) && (endPtr != 0) && (*endPtr == p)) {
    *endPtr = string;
    }
    return result;
}