Skip to content

Commit

Permalink
- throw hex parsing errors
Browse files Browse the repository at this point in the history
  • Loading branch information
anonymoussprocket committed Aug 18, 2020
1 parent c939370 commit bd5191a
Showing 1 changed file with 119 additions and 114 deletions.
233 changes: 119 additions & 114 deletions src/chain/tezos/TezosLanguageUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,130 +20,135 @@ export namespace TezosLanguageUtil {
let fieldType = hex.substring(offset, offset + 2);
offset += 2;

switch (fieldType) {
case '00': { // literal int or nat
const value = TezosMessageUtils.findInt(hex.substring(offset), 0, true);
code += `{ "int": "${value.value}" }`;
offset += value.length;
break;
}
case '01': { // literal string
const stringEnvelope = michelineHexToString(hex.substring(offset));
code += `{ "string": "${stringEnvelope.code}" }`;
offset += stringEnvelope.consumed;
break;
}
case '02': { // array
const length = parseInt(hex.substring(offset, offset + 8), 16);
offset += 8;
let buffer: string[] = [];
let consumed = 0;
while (consumed < length) {
try {
switch (fieldType) {
case '00': { // literal int or nat
const value = TezosMessageUtils.findInt(hex.substring(offset), 0, true);
code += `{ "int": "${value.value}" }`;
offset += value.length;
break;
}
case '01': { // literal string
const stringEnvelope = michelineHexToString(hex.substring(offset));
code += `{ "string": "${stringEnvelope.code}" }`;
offset += stringEnvelope.consumed;
break;
}
case '02': { // array
const length = parseInt(hex.substring(offset, offset + 8), 16);
offset += 8;
let buffer: string[] = [];
let consumed = 0;
while (consumed < length) {
let envelope = hexToMicheline(hex.substring(offset));
buffer.push(envelope.code);
consumed += envelope.consumed / 2; // plain bytes
offset += envelope.consumed; // hex-encoded two-char bytes
}
if (length === 0) {
code += '[]';
} else {
code += `[ ${buffer.join(', ')} ]`;
}
break;
}
case '03': { // bare primitive
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)} }`;
offset += 2;
break;
}
case '04': { // primitive with a set of annotations
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

const annEnvelope = michelineHexToAnnotations(hex.substring(offset));
code += `"annots": [ ${annEnvelope.code} ] }`;
offset += annEnvelope.consumed;
break;
}
case '05': { // primitive with an argument
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;
const envelope = hexToMicheline(hex.substring(offset));
code += `"args": [ ${envelope.code} ] }`;
offset += envelope.consumed;
break;
}
case '06': { // primitive with an argument an a set of annotations
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

const args = hexToMicheline(hex.substring(offset));
code += `"args": [ ${args.code} ], `;
offset += args.consumed;

const anns = michelineHexToAnnotations(hex.substring(offset));
code += `"annots": [ ${anns.code} ] }`;
offset += anns.consumed;
break;
}
case '07': { // primitive with two arguments
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

let buffer: string[] = [];
let envelope = hexToMicheline(hex.substring(offset));
buffer.push(envelope.code);
consumed += envelope.consumed / 2; // plain bytes
offset += envelope.consumed; // hex-encoded two-char bytes
offset += envelope.consumed;
envelope = hexToMicheline(hex.substring(offset));
buffer.push(envelope.code);
offset += envelope.consumed;

code += `"args": [ ${buffer.join(', ')} ] }`;
break;
}
if (length === 0) {
code += '[]';
} else {
code += `[ ${buffer.join(', ')} ]`;
case '08': { // primitive with two arguments and an annotation set
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

const arg0 = hexToMicheline(hex.substring(offset));
offset += arg0.consumed;
const arg1 = hexToMicheline(hex.substring(offset));
offset += arg1.consumed;
code += `"args": [ ${arg0.code}, ${arg1.code} ], `;

const anns = michelineHexToAnnotations(hex.substring(offset));
code += `"annots": [ ${anns.code} ] }`;
offset += anns.consumed;
break;
}
break;
}
case '03': { // bare primitive
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)} }`;
offset += 2;
break;
}
case '04': { // primitive with a set of annotations
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

const annEnvelope = michelineHexToAnnotations(hex.substring(offset));
code += `"annots": [ ${annEnvelope.code} ] }`;
offset += annEnvelope.consumed;
break;
}
case '05': { // primitive with an argument
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;
const envelope = hexToMicheline(hex.substring(offset));
code += `"args": [ ${envelope.code} ] }`;
offset += envelope.consumed;
break;
}
case '06': { // primitive with an argument an a set of annotations
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

const args = hexToMicheline(hex.substring(offset));
code += `"args": [ ${args.code} ], `;
offset += args.consumed;

const anns = michelineHexToAnnotations(hex.substring(offset));
code += `"annots": [ ${anns.code} ] }`;
offset += anns.consumed;
break;
}
case '07': { // primitive with two arguments
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

let buffer: string[] = [];
let envelope = hexToMicheline(hex.substring(offset));
buffer.push(envelope.code);
offset += envelope.consumed;
envelope = hexToMicheline(hex.substring(offset));
buffer.push(envelope.code);
offset += envelope.consumed;

code += `"args": [ ${buffer.join(', ')} ] }`;
break;
}
case '08': { // primitive with two arguments and an annotation set
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

const arg0 = hexToMicheline(hex.substring(offset));
offset += arg0.consumed;
const arg1 = hexToMicheline(hex.substring(offset));
offset += arg1.consumed;
code += `"args": [ ${arg0.code}, ${arg1.code} ], `;

const anns = michelineHexToAnnotations(hex.substring(offset));
code += `"annots": [ ${anns.code} ] }`;
offset += anns.consumed;
break;
}
case '09': { // primitive with an argument array and an optional anotation set
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;
case '09': { // primitive with an argument array and an optional anotation set
code += `{ "prim": ${hexToMichelineKeyword(hex, offset)}, `;
offset += 2;

let envelope = hexToMicheline('02' + hex.substring(offset)); // fake an array to re-use the parsing code
code += `"args": ${envelope.code}`;
offset += envelope.consumed - 2; // account for the inserted '02' above
let envelope = hexToMicheline('02' + hex.substring(offset)); // fake an array to re-use the parsing code
code += `"args": ${envelope.code}`;
offset += envelope.consumed - 2; // account for the inserted '02' above

if (hex.substring(offset, offset + 8) !== '00000000') {
const annEnvelope = michelineHexToAnnotations(hex.substring(offset));
if (annEnvelope.code.length > 2) { // more than empty quotes
code += `, "annots": [ ${annEnvelope.code} ] }`;
if (hex.substring(offset, offset + 8) !== '00000000') {
const annEnvelope = michelineHexToAnnotations(hex.substring(offset));
if (annEnvelope.code.length > 2) { // more than empty quotes
code += `, "annots": [ ${annEnvelope.code} ] }`;
}
offset += annEnvelope.consumed;
} else {
code += ' }';
offset += 8;
}
offset += annEnvelope.consumed;
} else {
code += ' }';
break;
}
case '0a': { // raw bytes
const length = parseInt(hex.substring(offset, offset + 8), 16);
offset += 8;
code += `{ "bytes": "${hex.substring(offset, offset + length * 2)}" }`;
offset += length * 2;
break;
}
break;
}
case '0a': { // raw bytes
const length = parseInt(hex.substring(offset, offset + 8), 16);
offset += 8;
code += `{ "bytes": "${hex.substring(offset, offset + length * 2)}" }`;
offset += length * 2;
break;
default: { throw new Error(`Unknown Micheline field type '${fieldType}' at offset ${offset} of '${hex}'`); }
}
default: { throw new Error(`Unknown Micheline field type '${fieldType}' at offset ${offset} of '${hex}'`); }
} catch (err) {
const m = `Nested hex parsing error (${err.message}) after: ${hex}, ${offset}, ${code}`;
throw new Error(m);
}

return { code: code, consumed: offset };
Expand Down

0 comments on commit bd5191a

Please sign in to comment.