gpt4 book ai didi

c - 为什么 printf 说明符格式 %n 不起作用?

转载 作者:行者123 更新时间:2023-12-03 15:36:10 27 4
gpt4 key购买 nike

这是我的代码:

#include <stdio.h>

int main(void) {
int n;

fprintf(stdout, "Hello%n World\n", &n);
fprintf(stdout, "n: %d\n", n);

return 0;
}

这是我的输出:
Hellon: 0
  • 为什么fprintf格式说明符 "%n"不行?
  • 为什么要打印的字符串被打断?

  • ISO/IEC 9899:201x C11 - 7.21.6.1 - fprintf 函数

    The conversion specifiers and their meanings are:

    (...)

    %n The argument shall be a pointer to signed integer into which is written the number of characters written to the output stream so far by this call to fprintf. No argument is converted, but one is consumed. If the conversion specification includes any flags, a field width, or a precision, the behavior is undefined. ...

    (...)



    这是我在 Code::Blocks 上使用的编译器版本:
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev
    0/mingw64/bin/../libexec/gcc/x86_64-w64-mingw32/8.1.0/lto-wrapper.exe
    Target: x86_64-w64-mingw32
    Configured with: ../../../src/gcc-8.1.0/configure --host=x86_64-w64-mingw32 --bu
    ild=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --prefix=/mingw64 --with-sysr
    oot=/c/mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64 --enable-shared --enable
    -static --disable-multilib --enable-languages=c,c++,fortran,lto --enable-libstdc
    xx-time=yes --enable-threads=posix --enable-libgomp --enable-libatomic --enable-
    lto --enable-graphite --enable-checking=release --enable-fully-dynamic-string --
    enable-version-specific-runtime-libs --disable-libstdcxx-pch --disable-libstdcxx
    -debug --enable-bootstrap --disable-rpath --disable-win32-registry --disable-nls
    --disable-werror --disable-symvers --with-gnu-as --with-gnu-ld --with-arch=noco
    na --with-tune=core2 --with-libiconv --with-system-zlib --with-gmp=/c/mingw810/p
    rerequisites/x86_64-w64-mingw32-static --with-mpfr=/c/mingw810/prerequisites/x86
    _64-w64-mingw32-static --with-mpc=/c/mingw810/prerequisites/x86_64-w64-mingw32-s
    tatic --with-isl=/c/mingw810/prerequisites/x86_64-w64-mingw32-static --with-pkgv
    ersion='x86_64-posix-seh-rev0, Built by MinGW-W64 project' --with-bugurl=https:/
    /sourceforge.net/projects/mingw-w64 CFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x
    86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x
    86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/
    include' CXXFLAGS='-O2 -pipe -fno-ident -I/c/mingw810/x86_64-810-posix-seh-rt_v6
    -rev0/mingw64/opt/include -I/c/mingw810/prerequisites/x86_64-zlib-static/include
    -I/c/mingw810/prerequisites/x86_64-w64-mingw32-static/include' CPPFLAGS=' -I/c/
    mingw810/x86_64-810-posix-seh-rt_v6-rev0/mingw64/opt/include -I/c/mingw810/prere
    quisites/x86_64-zlib-static/include -I/c/mingw810/prerequisites/x86_64-w64-mingw
    32-static/include' LDFLAGS='-pipe -fno-ident -L/c/mingw810/x86_64-810-posix-seh-
    rt_v6-rev0/mingw64/opt/lib -L/c/mingw810/prerequisites/x86_64-zlib-static/lib -L
    /c/mingw810/prerequisites/x86_64-w64-mingw32-static/lib '
    Thread model: posix
    gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)

    最佳答案

    Microsoft documentation 中所述, %n在您的 MinGW 系统上使用的 Microsoft C 库中默认禁用:

    Important

    Because the %n format is inherently insecure, it is disabled by default. If %n is encountered in a format string, the invalid parameter handler is invoked, as described in Parameter Validation. To enable %n support, see _set_printf_count_output.


    是否 %n微软声称的实际上是不安全的,这是非常值得商榷的。显示支持此声明的示例结合了此 printf函数使用可变格式字符串,攻击者可以通过缓冲区溢出错误更改该字符串。
    在某些 Microsoft 系统(但可能不是最新的)上,您可以通过以下方式修复您的程序:
    #include <stdio.h>

    int main(void) {
    int n;

    _set_printf_count_output(1);

    fprintf(stdout, "Hello%n World\n", &n);
    fprintf(stdout, "n: %d\n", n);

    return 0;
    }
    对于更便携的方法,这里有一个避免使用 %n 的解决方法。仍然得到相同的结果:
    #include <stdio.h>

    int main(void) {
    int n;

    n = fprintf(stdout, "Hello");
    fprintf(stdout, " World\n");
    fprintf(stdout, "n: %d\n", n);

    return 0;
    }
    输出:
    Hello World
    n: 5

    关于c - 为什么 printf 说明符格式 %n 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54957216/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com