首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

01- JavaScript 调用堆栈

什么是 JavaScript 调用栈,为什么它是必要的? JavaScript 引擎是一个单线程解析器,而单线程解析器由堆和单一调用栈组成。...本文旨在说明什么是调用堆栈以及为什么需要调用栈?对调用栈的理解有助于我们更加清晰的知道 函数的的层次结构和执行顺序 在 JavaScript 的引擎中工作方式。...调用堆栈主要用于函数调用,由于 调用堆栈是单个的,因此函数的执行从上到下一次性完成。这意味着调用栈是同步的。 对调用栈的理解对于异步编程至关重要,后面我们介绍。...是什么导致堆栈溢出? 当存在没有出口点的递归函数(调用自身的函数)时,将发生堆栈溢出。...综上所诉 调用堆栈的主要收获是: 它是单线程的,每次只能做一件事情。 代码执行是同步的 函数调用创建一个占用临时内存的堆栈 它的作用是 LIFO,先进后出

1.3K20

Python 之父的解析器系列之五:左递归 PEG 语法

基本的问题在于:使用递归下降解析器时,左递归堆栈溢出而导致程序终止。 【这是我的 PEG 系列的第 5 部分。...if term(): return True return False 也就是expr() 以调用expr() 开始,后者也以调用expr() 开始,以此类推……这只能以堆栈溢出而结束...试试看吧……我们可以尝试记录在调用堆栈上的 expr() 的(左递归)调用次数,并将其与下面表达式中“+” 运算的数量进行比较。如果调用堆栈的深度大于运算的数量,则应该返回 false。...我没有证明为什么这个算法总是有效的,不管这个语法有多疯狂。那是因为我实际上没有读过那个证明。...所以这个expr() 调用回到它的第二个备选项,并返回一个可怜的 term。

79930
您找到你想要的搜索结果了吗?
是的
没有找到

Rust 中的解析器组合因子(Parser combinators)

经典的子是,正则表达式例不接受 “ab”、“aabb”、“aaabbb”……类似地,不能用正则表达式解决插入语的匹配难题,而需要使用最简单的堆栈机器模型。 堆栈自动机,可以同时处于几种状态。...(@\* 将字符 '(' 与任何堆栈状态匹配;仅当堆栈为空时,ε@ε 在自动机到达 p 状态时即刻匹配。 因此,正则表达式远远不能提供足够的工具,以用来处理上下文无关语法。...但是,为什么我们说您永远不应该使用它们呢?实用性原因! 让我们看看 Regex Cookbook 中的一个例子(来自于于 medium 站点),这样我们就晓得,这是一个在业界使用的实际案例。...修饰构造,将通过解析(A)传递出现的任何潜在错误。 Result 中的 Ok 变量在(D)中构造,通过将 many1 输出(数值的动态数组),转换成一个无符号 64 位整数。...如果解析过程不是你产品或者你开发库的主要目标,那么解析器组合因子很可能对你的任务有足够的表现力和可执行力。我们希望你喜欢这篇文章,并且用解析器组合因子快乐地做解析。 谢谢您的阅读。

1.8K10

CVE-2019-0697:通过DHCP漏洞发现其余两个关键漏洞

因此,这些索引的值可能超过256,并导致在堆栈上为阵列分配的内存之外进行写入。要导致第一个阵列溢出,DHCP服务器发送超过256个选项的数据包就足够了。...因此,我们有一个溢出,我们控制每个第四个字节,其余的在覆盖时归零。 测试漏洞的最简单方法是覆盖存储在堆栈中的函数的安全cookie,这将导致安全检查相关的异常。...我们发送以这种方式形成的数据包以响应来自DHCP客户端的请求,并且在客户端的计算机上,我们在相应的svchost.exe进程中捕获异常: 正如我们从堆栈跟踪中看到的那样,来自我们数据包的选项标识覆盖了堆栈...在系统上由于所有现代保护机制,缓冲区堆栈溢出是一个复杂且难以利用的漏洞。另一方面,我们不要忘记所有这些机制都保护返回地址和异常处理程序不被覆盖,防止在未分配的内存位置中执行代码,或者阻止预测地址。...但是,它们无法阻止在溢出缓冲区和返回地址之间覆盖存储在堆栈中的局部变量。 DhcpExtractFullOptions函数包含该范围内的几个潜在危险变量。 我们再次写信给微软,告知我们发现的错误。

58910

Python 之父的解析器系列之四:可视化 PEG 解析

中间的单行部分展示了标记缓冲区的内容,光标指向下一个要解析的标记。 在底部,我们呈现 packrat 解析算法使用的记忆缓存。它的条目类似于一些解析器堆栈条目(具有结果的条目)。 ?...在显示出来的解析器堆栈和缓存中,已返回的调用被显示成function(args) -> result 。有时解析器堆栈显示几个已返回的方法——我这样做是为了减少显示时的“跳跃性”。...(说到“跳跃”,顶部显示的解析器堆栈会在一个调用被添加到堆栈时,向上移动,而当从堆栈中弹出一个调用时,它则向下移动。似乎我们的眼睛跟随这样的动作不会有太大问题——至少我没有。...,有时下一个标记还未显示(例如,在最开始时,堆栈在标记'aap' 被显示之前,就增长了几个条目)。...这正是解析器所看到的:标记缓冲区被延迟地填充,并且在解析器通过调用 expect() 来请求它们之前,并不会扫描标记。一旦标记出现在缓冲区中,它就会保留在那里,即便在解析器回溯时也如此。

66010

TiDB 源码阅读系列文章(五)TiDB SQL Parser 的实现

对于 Java 程序员来说,更熟悉的是 ANTLR,ANTLR 4 提供了 Listener+Visitor 组合接口, 不需要在语法定义中嵌入actions,使应用代码和语法定义解耦。...从左向右移动,我们将读取的 token 压入堆栈,当发现堆栈中的内容匹配了某个产生式的右侧,则将匹配的项从堆栈中弹出,将该产生式左侧的非终结压入堆栈。...这个过程持续进行,直到读取完所有的 tokens,并且只有启始非终结(本例为 program)保留在堆栈中。...有了上面的背景知识,对 TiDB 的 SQL Parser 模块相对容易理解一些。TiDB 的词法解析使用的 手写的解析器(这是出于性能考虑),语法解析采用 goyacc。...压入堆栈的项可能是 终结,也就是 token,它的类型可以是item 或 ident; 这个项也可能是 非终结,即产生式的左侧,它的类型可以是 expr 、 statement 、 item 或 ident

4.5K100

TiDB SQL Parser 的实现

对于Java程序员来说,更熟悉的是ANTLR,ANTLR 4 提供了 Listener+Visitor 组合接口, 不需要在语法定义中嵌入actions,使应用代码和语法定义解耦。...从左向右移动,我们将读取的token压入堆栈,当发现堆栈中的内容匹配了某个产生式的右侧,则将匹配的项从堆栈中弹出,将该产生式左侧的非终结压入堆栈。...这个过程持续进行,直到读取完所有的tokens,并且只有启始非终结(本例为 program)保留在堆栈中。...有了上面的背景知识,对TiDB 的 SQL Parser 模块相对容易理解一些。先看SQL语法规则文件parser.y,goyacc 就是根据这个文件生成SQL语法解析器的。...压入堆栈的项可能是终结,也就是 token,它的类型可以是item 或 ident; 这个项也可能是非终结,即产生式的左侧,它的类型可以是 expr 、 statement 、 item 或 ident

36710

Pwn2Own-Safari 漏洞 CVE-2021-3073 分析与利用

shellcode, 默认向localhost:1337请求并加载第二阶段(沙盒逃逸)shellcode, 以完成任意代码执行....(m_stackSize)以及整个解析过程中栈容量的最大值(m_maxStackSize), 当前堆栈大小有助于将抽象堆栈位置转换为本地堆栈的偏移量, 而最大堆栈值则将决定函数序言期间将分配的栈空间大小...漏洞利用 触发漏洞 要触发整数溢出问题, 我们需要构造出能使解析器执行2^32次push操作的wasm函数, POC最终选择使用之前提到的多值范式, 以及解析器对unreachable代码的处理相结合的方法...之前提到多值范式没有说的一点是, 它允许块拥有任意数量的返回值, 在JavaScriptCore的实现中也没有强制规定该数量的上限, 这允许我们构造具有大量返回值的块 解析器执行一些非常基本的分析来确定代码是否为无法访问或是死代码...stage2_server可以成功建立连接 使用lldb调试WebContent进程成功获取到shellcode中的int3断点并查看内存布 总结 这个漏洞本身还是非常好理解的, 从隐式类型转换到整数溢出再到栈溢出

1.1K10

JS执行上下文与调用栈

本文分享 了 JavaScript 基础的两个方面:执行上下文和调用堆栈。...调用栈 调用栈是解析器(如浏览器中的的javascript解析器)的一种机制,可以在脚本调用多个函数时,跟踪每个函数在完成执行时应该返回控制的点。...任何被这个函数调用的函数进一步添加到调用栈中,并且运行到它们被上个程序调用的位置。 当函数运行结束后,解释器将它从堆栈中取出,并在主代码列表中继续执行代码。...如果栈占用的空间比分配给它的空间还大,那么则会导致“栈溢出”错误。...这就是为什么你可以在声明之前访问 var 定义的变量(虽然是 undefined),但是在声明之前访问 let 和 const 的变量会得到一个引用错误。 这就是我们说的变量声明提升。

1.5K10

MIT 6.858 计算机系统安全讲义 2014 秋季(一)

要连接到启用 SSL 的网站,Web 浏览器验证证书。 证书是服务器主机名和加密密钥的组合, 由某些受信任的证书颁发机构(CA)签名。...A: 金丝雀必须放在堆栈上返回地址的“前面”,这样任何溢出重写返回地址也将重写金丝雀。...基本上,我们创建了一种新类型的机器,它由堆栈指针驱动,而不是常规指令指针!随着堆栈指针沿着堆栈移动,它执行的小工具的代码来自预先存在的程序代码,数据来自缓冲区溢出创建的堆栈数据。...为什么 setuid 二进制文件在安全方面可能是个坏主意? 对手(二进制调用者)操纵进程的许多方法。 在 Unix 中,执行的进程继承环境变量、文件描述等。...例如:Unix 上的文件描述是文件的能力。 程序无法制造未经合法获取的文件描述为什么不? 操作系统创建和管理文件描述。应用程序无法伪造文件描述

11510

bison解析中lookahead前瞻工作原理

bison解析器在发现一次匹配后,继续向前看一个lookahead,再决定做什么。...具体步骤: 当读到一个token时,并不立即shift进入堆栈,而是把他当成lookahead token(不入栈)。 然后解析器就可以执行栈上的匹配动作了,匹配上就可以reduce。...Bison会通过选择shift来解决这些冲突(除非运算优先级声明)。...推入解析器栈的值不仅仅看做是一个个的token,它们表示的是终结、非终结组成的序列(栈顶的token序列),token就是状态机的状态。...转移指令可能是shift:解析器堆栈入栈。 转移指令可能是recude:解析器堆栈出栈状态(token/tolen序列),入栈一个替换的状态(token)。

1.4K70

javacc功能一览

从左到右(即,输入按读取的顺序处理)和R-最右派生 LL仅从堆栈的根非终结开始。 LR在堆栈上仅以根非终结结尾。 当堆栈为空时,LL结束。 LR从空堆栈开始。 LL扩展为非末尾。...LL读取终端时,将其弹出堆栈之一。 LR在将它们压入堆栈时读取端子。 LL使用分析树的预遍历。 LR使用解析树的后序遍历。 在LL解析器期间,解析器在两个动作之间连续选择。...预测:基于最左边的非终结和一些先行标记。 匹配:将最左侧的猜测终端符号与输入的最左侧未使用符号匹配。 在LR解析器期间,解析器在两个动作之间连续选择。...自上而下的解析器还有许多其他优点(除了更通用的语法外),例如,调试起来更容易,能够解析到语法中的任何非终结[4],还可以向上传递值(属性)在解析期间在解析树中向下移动。...;} } 生成代码结构如下图: image-20201102163349917.png) 调用方式 在Calculator.jj上运行main方法,在Program arguments中传入1+2,即输出结果

1.8K10

谈谈我对 JavaScript执行上下文栈理解

function bar () { return 'I am bar'; } return bar(); } foo(); 对应图解如下: 执行上下文的数量限制(堆栈溢出...) 执行上下文可存在多个,虽然没有明确的数量限制,但如果超出栈分配的空间,造成堆栈溢出。...调用栈 调用栈是解析器(如浏览器中的的 JavaScript 解析器)的一种机制,可以在脚本调用多个函数时,跟踪每个函数在完成执行时应该返回控制的点。...任何被这个函数调用的函数进一步添加到调用栈中,并且运行到它们被上个程序调用的位置。 当函数运行结束后,解释器将它从堆栈中取出,并在主代码列表中继续执行代码。...如果栈占用的空间比分配给它的空间还大,那么则会导致“栈溢出”错误。

25630

看我利用传真功能漏洞渗透进入企业内网

JPEG解析器 存在一些说不清的原因,这种特定固件的开发者倾向于把主流开源项目中实现的模块功能进行重新编写,改善优化,也就是说,他们不会用开源的libjpeg标准库,转而是用自己的 JPEG 解析器。...CVE-2018-5924 – 解析DHT标记时的堆栈缓冲区溢出漏洞 由于上一个漏洞的发现是标准实现中不应支持的标记所导致的,所以,我们继续把关注点扩展到了其它标记身上。...第二个解析循环会使用之前的长度字段,从传真文件中拷贝数据到本地堆栈缓冲区中 一个简单的计算就能知晓具体的漏洞成因:16 * 255 = 4080 > 256,也就是说,我们可以构造一个大容量可控且无限制的堆栈缓冲区溢出...在Devil’s Ivy漏洞中,其中的调试exploit利用代码,也是利用了一个堆栈溢出漏洞,那么这里我们也是一样,仅只需要对调试exploit作出一些小修改即可。...而且文件的fd文件描述也存储在可访问的全局变量中,所以, 我们编写了一个基于文件的加载器,该加载器从文件中读取Payload,然后把它加载到内存中去。

1.4K10

人人都能读懂的编译器原理

因为从复杂的、人类可读的代码直接转化成0/1二进制很复杂,所以编译器在产生可运行程序之前有多个步骤: 从你给定的源代码中读取单个词。 把这些词按照单词、数字、符号、运算进行分类。...这一步的关键就在于 我们把字符组合成我们需要的单词、标识、符号等等。 词法分析大多都不需要处理逻辑运算像是算出 2+2 – 其实这个表达式只有三种 标记:一个数字:2,一个加号,另外一个数字:2。...如果你可以阅读过上面的代码,并且弄懂了这样做的含义,接下来的 Rust 分词器组合数字为32位整数,加号就最后了标记值 Plus(加). https://play.rust-lang.org/?...在一种编程语言的编译器中,词法解析器可能需要许多不同类型的标记。例如:符号,数字,标识,字符串,操作等。想知道要从源文件中提取怎样的标记完全取决于编程语言本身。...(对于 Rust 是 -O ) 如果你对于编译器是在汇编语言中怎样把一个本地变量保存到内存中感兴趣的话,这篇文章(“代码生成”部分)非常详细地解释了堆栈的相关知识。

1.5K11

Python之父发文,将重构现有核心解析器

几年前,有人问 Python 是否转换用 PEG 解析器(或者是 PEG 语法,我不记得确切内容、谁说的、什么时候说的)。我稍微看过这个主题,但没有头绪,就放弃了。...由于前向的单一标记解析器无法确定它查看的是一个表达式的开头,还是一个赋值。在一个语句的开头,解析器需要根据它看到的第一个标记,来决定它要查看的 statement 的可选内容。(为什么呢?...但是 expr 与 assignment 都能以 NAME 标记开头,因此就会引起歧义(ambiguous),pgen 拒绝我们的语法。...三十年前,我有充分的理由来使用单一前向标记的解析技术:内存很昂贵。LL(1) 解析(以及其它技术像 LALR(1),因 YACC 而著名)使用状态机和堆栈(一种“下推自动机”)来有效地构造解析树。...为什么不直接从解析树编译呢?

98110

网络攻防实战技术之——缓冲区溢出

缓冲区溢出   如果用户输入的数据长度超出了程序为其分配的内存空间,这些数据就会覆盖程序为其它数据分配的内存空间,形成所谓的缓冲区溢出 ? 为什么缓冲区溢出? 1....理解缓冲区溢出的原理 Windows环境下的堆栈 1. 程序空间由何构成? 2. 堆栈是什么? 3. 堆栈里面放的都是什么信息? 4. 程序使用超过了堆栈默认的大小怎么办? 5....大object向小object复制数据(字符串或整型),容纳不下造成溢出   2. 溢出覆盖一些关键性数据(返回地址、管理数据、异常处理或文件指针等)   3....高级功能     1) 抗NIDS检测     2) 穿透防火墙 Shellcode不通用  Shellcode为什么不通用   1....黑客可以利用的几个条件:     (1)参数个数不固定造成访问越界数据     (2)利用%n/%hn格式写入跳转地址     (3)利用附加格式控制跳转地址的值  一个简单的例子: int main

5.6K41

用 350 行代码从零开始,将 Lisp 编译成 JavaScript

我们将会: 自定义语言,并用它编写一个简单的程序 实现一个简单的解析器组合器 为该语言实现一个解析器 为该语言实现一个美观的打印器 为我们的用途定义 JavaScript 的一个子集 实现代码转译器,将代码转译成我们定义的...2、实现一个简单的解析器组合库 我们要做的第一件事情是定义一个 嵌入式领域专用语言(Embedded Domain Specific Language)(EDSL),我们会用它来定义我们的语言解析器。...现在我们想让这个解析器更灵活,我们将会定义一些常用类型的实例。这些实例让我们能够将小巧的解析器和复杂的解析器结合在一起(因此它的名字叫做 “解析器组合器”)。 第一个是 Functor 实例。...当它完成的时候,返回成功运行的解析器列表。many1 做的事情是一样的,但解析失败时它至少抛出一次异常。...练习 :实现一个 EOF(end of file/input,即文件或输入终止解析器组合器。 3、为我们的语言实现解析器 我们会用自顶而下的方法定义解析器

96640
领券