Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@tact-lang/opcode

Package Overview
Dependencies
Maintainers
3
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@tact-lang/opcode - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

src/decompiler/__snapshots__/decompiler.spec.ts.snap

5

CHANGELOG.md

@@ -8,2 +8,7 @@ # Changelog

## [0.0.6] - 2023-03-24
## Fixed
- Fix invalid cell hash and offset in dict-based parser
## [0.0.5] - 2023-03-24

@@ -10,0 +15,0 @@

37

dist/decompiler/decompileAll.js

@@ -53,3 +53,3 @@ "use strict";

});
extracted.set(name, { ref: true, rendered: w.end(), src: cell });
extracted.set(name, { ref: true, rendered: w.end(), src: cell, srcOffset: 0 });
return name;

@@ -59,2 +59,3 @@ }

let name = knownMethods_1.knownMethods[key] || '?fun_' + (unknownIndex++);
let body = value.cell.beginParse().skip(value.offset).asCell();
let w = new Writer_1.Writer();

@@ -64,3 +65,3 @@ w.inIndent(() => {

decompileCell({
src: value,
src: body,
root: false,

@@ -73,3 +74,8 @@ writer: w,

});
extracted.set(name, { ref: false, rendered: w.end(), src: value });
extracted.set(name, {
ref: false,
rendered: w.end(),
src: value.cell,
srcOffset: value.offset
});
}

@@ -85,3 +91,3 @@ // Render methods

let opstr = `${key} ${value.ref ? 'PROCREF' : 'PROC'}:<{`;
writer.append(printer({ op: opstr, offset: 0, length: 0, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: value.srcOffset, length: 0, hash, cell: value.src }, writer.indent));
writer.inIndent(() => {

@@ -93,3 +99,3 @@ value.rendered.split('\n').forEach(line => {

opstr = `}>`;
writer.append(printer({ op: opstr, offset: 0, length: 0, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: value.srcOffset, length: 0, hash, cell: value.src }, writer.indent));
}

@@ -106,3 +112,3 @@ });

let opstr = `${id} INLINECALLDICT`;
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash, cell: args.src }, writer.indent));
continue;

@@ -119,3 +125,3 @@ }

let opstr = '<{';
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash, cell: args.src }, writer.indent));
writer.inIndent(() => {

@@ -131,3 +137,3 @@ decompileCell({

opstr = '}> ' + op.op.code;
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash, cell: args.src }, writer.indent));
continue;

@@ -142,3 +148,3 @@ }

let opstr = (0, opcodeToString_1.opcodeToString)(op.op);
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash, cell: args.src }, writer.indent));
}

@@ -168,8 +174,17 @@ }

serialize: (src, builder) => {
return builder.storeSlice(src.beginParse());
throw Error('Not implemented');
},
parse: (src) => {
return src.asCell();
let bitsReader = src._reader.clone();
let offset = bitsReader._offset;
bitsReader.reset();
let bits = bitsReader.loadBits(bitsReader.remaining);
let b = (0, ton_core_1.beginCell)()
.storeBits(bits);
while (src.remainingRefs > 0) {
b.storeRef(src.loadRef());
}
return { offset, cell: b.endCell() };
}
};
}
/// <reference types="node" />
import { Cell } from "ton-core";
import { Cell, Slice } from "ton-core";
import { OpCode } from "../codepage/opcodes.gen";

@@ -14,4 +14,4 @@ export type DecompiledOpCode = OpCode | {

export declare function decompile(args: {
src: Cell | Buffer;
src: Cell | Slice | Buffer;
allowUnknown?: boolean;
}): DecompiledInstruction[];

@@ -7,14 +7,16 @@ "use strict";

function decompile(args) {
// Load cell
let cell;
// Result collection
let result = [];
// Load slice
let sc;
if (Buffer.isBuffer(args.src)) {
cell = ton_core_1.Cell.fromBoc(args.src)[0];
sc = ton_core_1.Cell.fromBoc(args.src)[0].beginParse();
}
else if (args.src instanceof ton_core_1.Cell) {
sc = args.src.beginParse();
}
else {
cell = args.src;
sc = args.src;
}
// Result collection
let result = [];
// Parse cell
let sc = cell.beginParse();
let scl = sc.remainingBits;

@@ -21,0 +23,0 @@ let sco = 0;

@@ -0,4 +1,6 @@

import { Cell } from "ton-core";
export type Printer = (src: string | {
op: string;
hash: string;
cell: Cell;
offset: number;

@@ -5,0 +7,0 @@ length: number;

{
"name": "@tact-lang/opcode",
"version": "0.0.5",
"version": "0.0.6",
"main": "dist/index.js",

@@ -5,0 +5,0 @@ "repository": "https://github.com/tact-lang/ton-opcode.git",

@@ -29,2 +29,8 @@ import { decompileAll } from "./decompileAll";

it('should decompile highload wallet', () => {
let wallet = Buffer.from('te6ccgEBCAEAlwABFP8A9KQT9LzyyAsBAgEgAgMCAUgEBQC48oMI1xgg0x/TH9MfAvgju/Jj7UTQ0x/TH9P/0VEyuvKhUUS68qIE+QFUEFX5EPKj9ATR+AB/jhYhgBD0eG+lIJgC0wfUMAH7AJEy4gGz5lsBpMjLH8sfy//J7VQABNAwAgFIBgcAF7s5ztRNDTPzHXC/+AARuMl+1E0NcLH4', 'base64');
let res = decompileAll({ src: wallet });
expect(res).toMatchSnapshot();
});
it('should decompile wallet v4 speedtest', () => {

@@ -31,0 +37,0 @@ const wallet = Buffer.from('te6ccgECFAEAAtQAART/APSkE/S88sgLAQIBIAIDAgFIBAUE+PKDCNcYINMf0x/THwL4I7vyZO1E0NMf0x/T//QE0VFDuvKhUVG68qIF+QFUEGT5EPKj+AAkpMjLH1JAyx9SMMv/UhD0AMntVPgPAdMHIcAAn2xRkyDXSpbTB9QC+wDoMOAhwAHjACHAAuMAAcADkTDjDQOkyMsfEssfy/8QERITAubQAdDTAyFxsJJfBOAi10nBIJJfBOAC0x8hghBwbHVnvSKCEGRzdHK9sJJfBeAD+kAwIPpEAcjKB8v/ydDtRNCBAUDXIfQEMFyBAQj0Cm+hMbOSXwfgBdM/yCWCEHBsdWe6kjgw4w0DghBkc3RyupJfBuMNBgcCASAICQB4AfoA9AQw+CdvIjBQCqEhvvLgUIIQcGx1Z4MesXCAGFAEywUmzxZY+gIZ9ADLaRfLH1Jgyz8gyYBA+wAGAIpQBIEBCPRZMO1E0IEBQNcgyAHPFvQAye1UAXKwjiOCEGRzdHKDHrFwgBhQBcsFUAPPFiP6AhPLassfyz/JgED7AJJfA+ICASAKCwBZvSQrb2omhAgKBrkPoCGEcNQICEekk30pkQzmkD6f+YN4EoAbeBAUiYcVnzGEAgFYDA0AEbjJftRNDXCx+AA9sp37UTQgQFA1yH0BDACyMoHy//J0AGBAQj0Cm+hMYAIBIA4PABmtznaiaEAga5Drhf/AABmvHfaiaEAQa5DrhY/AAG7SB/oA1NQi+QAFyMoHFcv/ydB3dIAYyMsFywIizxZQBfoCFMtrEszMyXP7AMhAFIEBCPRR8qcCAHCBAQjXGPoA0z/IVCBHgQEI9FHyp4IQbm90ZXB0gBjIywXLAlAGzxZQBPoCFMtqEssfyz/Jc/sAAgBsgQEI1xj6ANM/MFIkgQEI9Fnyp4IQZHN0cnB0gBjIywXLAlAFzxZQA/oCE8tqyx8Syz/Jc/sAAAr0AMntVA==', 'base64');

@@ -1,2 +0,2 @@

import { Cell, Dictionary, DictionaryValue } from "ton-core";
import { beginCell, BitReader, Cell, Dictionary, DictionaryValue } from "ton-core";
import { opcodeToString } from "../codepage/opcodeToString";

@@ -33,7 +33,7 @@ import { Maybe } from "../utils/maybe";

let dictCell = opcodes[1].op.args[1];
let dict = Dictionary.loadDirect<number, Cell>(Dictionary.Keys.Int(dictKeyLen), createCodeCell(), dictCell);
let dict = Dictionary.loadDirect<number, { offset: number, cell: Cell }>(Dictionary.Keys.Int(dictKeyLen), createCodeCell(), dictCell);
// Extract all methods
let unknownIndex = 0;
let extracted = new Map<string, { ref: boolean, rendered: string, src: Cell }>();
let extracted = new Map<string, { ref: boolean, rendered: string, src: Cell, srcOffset: number }>();
let callRefs = new Map<string, string>();

@@ -65,3 +65,3 @@ function extract(cell: Cell) {

});
extracted.set(name, { ref: true, rendered: w.end(), src: cell });
extracted.set(name, { ref: true, rendered: w.end(), src: cell, srcOffset: 0 });
return name;

@@ -71,2 +71,3 @@ }

let name = knownMethods[key] || '?fun_' + (unknownIndex++);
let body = value.cell.beginParse().skip(value.offset).asCell();
let w = new Writer();

@@ -76,3 +77,3 @@ w.inIndent(() => {

decompileCell({
src: value,
src: body,
root: false,

@@ -85,3 +86,8 @@ writer: w,

});
extracted.set(name, { ref: false, rendered: w.end(), src: value });
extracted.set(name, {
ref: false,
rendered: w.end(),
src: value.cell,
srcOffset: value.offset
});
}

@@ -98,3 +104,3 @@

let opstr = `${key} ${value.ref ? 'PROCREF' : 'PROC'}:<{`;
writer.append(printer({ op: opstr, offset: 0, length: 0, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: value.srcOffset, length: 0, hash, cell: value.src }, writer.indent));
writer.inIndent(() => {

@@ -106,3 +112,3 @@ value.rendered.split('\n').forEach(line => {

opstr = `}>`;
writer.append(printer({ op: opstr, offset: 0, length: 0, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: value.srcOffset, length: 0, hash, cell: value.src }, writer.indent));
}

@@ -121,3 +127,3 @@ });

let opstr = `${id} INLINECALLDICT`;
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash, cell: args.src }, writer.indent));
continue;

@@ -135,3 +141,3 @@ }

let opstr = '<{';
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash, cell: args.src }, writer.indent));
writer.inIndent(() => {

@@ -147,3 +153,3 @@ decompileCell({

opstr = '}> ' + op.op.code;
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash, cell: args.src }, writer.indent));
continue;

@@ -160,3 +166,3 @@ }

let opstr = opcodeToString(op.op);
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash }, writer.indent));
writer.append(printer({ op: opstr, offset: op.offset, length: op.length, hash, cell: args.src }, writer.indent));
}

@@ -183,11 +189,20 @@ }

function createCodeCell(): DictionaryValue<Cell> {
function createCodeCell(): DictionaryValue<{ offset: number, cell: Cell }> {
return {
serialize: (src, builder) => {
return builder.storeSlice(src.beginParse());
throw Error('Not implemented');
},
parse: (src) => {
return src.asCell();
let bitsReader = ((src as any)._reader.clone() as BitReader);
let offset = (bitsReader as any)._offset as number;
bitsReader.reset();
let bits = bitsReader.loadBits(bitsReader.remaining);
let b = beginCell()
.storeBits(bits);
while (src.remainingRefs > 0) {
b.storeRef(src.loadRef());
}
return { offset, cell: b.endCell() };
}
};
}

@@ -22,6 +22,5 @@ import { Cell } from "ton-core";

let res = decompile({ src: wallet });
console.warn(res);
// console.warn(original);
expect(res).toMatchSnapshot();
}
});
});

@@ -1,2 +0,2 @@

import { beginCell, Cell } from "ton-core";
import { beginCell, Cell, Slice } from "ton-core";
import { loadOpcode } from "../codepage/loadOpcode";

@@ -12,17 +12,18 @@ import { OpCode } from "../codepage/opcodes.gen";

export function decompile(args: { src: Cell | Buffer, allowUnknown?: boolean }): DecompiledInstruction[] {
export function decompile(args: { src: Cell | Slice | Buffer, allowUnknown?: boolean }): DecompiledInstruction[] {
// Load cell
let cell: Cell;
// Result collection
let result: DecompiledInstruction[] = [];
// Load slice
let sc: Slice;
if (Buffer.isBuffer(args.src)) {
cell = Cell.fromBoc(args.src)[0];
sc = Cell.fromBoc(args.src)[0].beginParse();
} else if (args.src instanceof Cell) {
sc = args.src.beginParse();
} else {
cell = args.src;
sc = args.src;
}
// Result collection
let result: DecompiledInstruction[] = [];
// Parse cell
let sc = cell.beginParse();
let scl = sc.remainingBits;

@@ -29,0 +30,0 @@ let sco = 0;

@@ -1,3 +0,5 @@

export type Printer = (src: string | { op: string, hash: string, offset: number, length: number }, indent: number) => string;
import { Cell } from "ton-core";
export type Printer = (src: string | { op: string, hash: string, cell: Cell, offset: number, length: number }, indent: number) => string;
export function createTextPrinter(indentWidth: number): Printer {

@@ -4,0 +6,0 @@ return (src, indent) => {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc