+248
| /* | ||
| * ctf.js | ||
| * | ||
| * Understand and parse all of the different JSON formats of CTF data and | ||
| * translate that into a series of node-ctype friendly pieces. The reason for | ||
| * the abstraction is to handle different changes in the file format. | ||
| * | ||
| * We have to be careful here that we don't end up using a name that is already | ||
| * a built in type. | ||
| */ | ||
| var mod_assert = require('assert'); | ||
| var ASSERT = mod_assert.ok; | ||
| var ctf_versions = [ '1.0' ]; | ||
| var ctf_entries = [ 'integer', 'float', 'typedef', 'struct' ]; | ||
| var ctf_deftypes = [ 'int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t', | ||
| 'uint32_t', 'float', 'double' ]; | ||
| function ctfParseInteger(entry, ctype) | ||
| { | ||
| var name, sign, len, type; | ||
| name = entry['name']; | ||
| if (!('signed' in entry['integer'])) | ||
| throw (new Error('Malformed CTF JSON: integer missing ' + | ||
| 'signed value')); | ||
| if (!('length' in entry['integer'])) | ||
| throw (new Error('Malformed CTF JSON: integer missing ' + | ||
| 'length value')); | ||
| sign = entry['integer']['signed']; | ||
| len = entry['integer']['length']; | ||
| type = null; | ||
| if (sign && len == 1) | ||
| type = 'uint8_t'; | ||
| else if (len == 1) | ||
| type = 'int8_t'; | ||
| else if (sign && len == 2) | ||
| type = 'uint16_t'; | ||
| else if (len == 2) | ||
| type = 'int16_t'; | ||
| else if (sign && len == 4) | ||
| type = 'uint32_t'; | ||
| else if (len == 4) | ||
| type = 'int32_t'; | ||
| /* | ||
| * TODO: Add this back in once the parser supports 64-bit values | ||
| * else if (sign && len == 8) | ||
| * type = 'uint64_t'; | ||
| * else if (len == 8) | ||
| * type = 'int64_t'; | ||
| */ | ||
| if (type === null) | ||
| throw (new Error('Malformed CTF JSON: integer has ' + | ||
| 'unsupported length and sign - ' + len + '/' + sign)); | ||
| /* | ||
| * This means that this is the same as one of our built in types. If | ||
| * that's the case defining it would be an error. So instead of trying | ||
| * to typedef it, we'll return here. | ||
| */ | ||
| if (name == type) | ||
| return; | ||
| if (name == 'char') { | ||
| ASSERT(type == 'uint8_t'); | ||
| return; | ||
| } | ||
| ctype.typedef(name, type); | ||
| } | ||
| function ctfParseFloat(entry, ctype) | ||
| { | ||
| var name, len; | ||
| name = entry['name']; | ||
| if (!('length' in entry['float'])) | ||
| throw (new Error('Malformed CTF JSON: float missing ' + | ||
| 'length value')); | ||
| len = entry['float']['length']; | ||
| if (len != 4 && len != 8) | ||
| throw (new Error('Malformed CTF JSON: float has invalid ' + | ||
| 'length value')); | ||
| if (len == 4) { | ||
| if (name == 'float') | ||
| return; | ||
| ctype.typedef(name, 'float'); | ||
| } else if (len == 8) { | ||
| if (name == 'double') | ||
| return; | ||
| ctype.typedef(name, 'double'); | ||
| } | ||
| } | ||
| function ctfParseTypedef(entry, ctype) | ||
| { | ||
| var name, type, ii; | ||
| name = entry['name']; | ||
| if (typeof (entry['typedef']) != 'string') | ||
| throw (new Error('Malformed CTF JSON: typedef value in not ' + | ||
| 'a string')); | ||
| type = entry['typedef']; | ||
| /* | ||
| * We need to ensure that we're not looking at type that's one of our | ||
| * built in types. Traditionally in C a uint32_t would be a typedef to | ||
| * some kind of integer. However, those size types are built ins. | ||
| */ | ||
| for (ii = 0; ii < ctf_deftypes.length; ii++) { | ||
| if (name == ctf_deftypes[ii]) | ||
| return; | ||
| } | ||
| ctype.typedef(name, type); | ||
| } | ||
| function ctfParseStruct(entry, ctype) | ||
| { | ||
| var name, type, ii, val, index, member, push; | ||
| member = []; | ||
| if (!Array.isArray(entry['struct'])) | ||
| throw (new Error('Malformed CTF JSON: struct value is not ' + | ||
| 'an array')); | ||
| for (ii = 0; ii < entry['struct'].length; ii++) { | ||
| val = entry['struct'][ii]; | ||
| if (!('name' in val)) | ||
| throw (new Error('Malformed CTF JSON: struct member ' + | ||
| 'missing name')); | ||
| if (!('type' in val)) | ||
| throw (new Error('Malformed CTF JSON: struct member ' + | ||
| 'missing type')); | ||
| if (typeof (val['name']) != 'string') | ||
| throw (new Error('Malformed CTF JSON: struct member ' + | ||
| 'name isn\'t a string')); | ||
| if (typeof (val['type']) != 'string') | ||
| throw (new Error('Malformed CTF JSON: struct member ' + | ||
| 'type isn\'t a string')); | ||
| /* | ||
| * CTF version 2 specifies array names as <type> [<num>] where | ||
| * as node-ctype does this as <type>[<num>]. | ||
| */ | ||
| name = val['name']; | ||
| type = val['type']; | ||
| index = type.indexOf(' ['); | ||
| if (index != -1) { | ||
| type = type.substring(0, index) + | ||
| type.substring(index + 1, type.length); | ||
| } | ||
| push = {}; | ||
| push[name] = { 'type': type }; | ||
| member.push(push); | ||
| } | ||
| name = entry['name']; | ||
| ctype.typedef(name, member); | ||
| } | ||
| function ctfParseEntry(entry, ctype) | ||
| { | ||
| var ii, found; | ||
| if (!('name' in entry)) | ||
| throw (new Error('Malformed CTF JSON: entry missing "name" ' + | ||
| 'section')); | ||
| for (ii = 0; ii < ctf_entries.length; ii++) { | ||
| if (ctf_entries[ii] in entry) | ||
| found++; | ||
| } | ||
| if (found === 0) | ||
| throw (new Error('Malformed CTF JSON: found no entries')); | ||
| if (found >= 2) | ||
| throw (new Error('Malformed CTF JSON: found more than one ' + | ||
| 'entry')); | ||
| if ('integer' in entry) { | ||
| ctfParseInteger(entry, ctype); | ||
| return; | ||
| } | ||
| if ('float' in entry) { | ||
| ctfParseFloat(entry, ctype); | ||
| return; | ||
| } | ||
| if ('typedef' in entry) { | ||
| ctfParseTypedef(entry, ctype); | ||
| return; | ||
| } | ||
| if ('struct' in entry) { | ||
| ctfParseStruct(entry, ctype); | ||
| return; | ||
| } | ||
| ASSERT(false, 'shouldn\'t reach here'); | ||
| } | ||
| function ctfParseJson(json, ctype) | ||
| { | ||
| var version, ii; | ||
| ASSERT(json); | ||
| ASSERT(ctype); | ||
| if (!('metadata' in json)) | ||
| throw (new Error('Invalid CTF JSON: missing metadata section')); | ||
| if (!('ctf2json_version' in json['metadata'])) | ||
| throw (new Error('Invalid CTF JSON: missing ctf2json_version')); | ||
| version = json['metadata']['ctf2json_version']; | ||
| for (ii = 0; ii < ctf_versions.length; ii++) { | ||
| if (ctf_versions[ii] == version) | ||
| break; | ||
| } | ||
| if (ii == ctf_versions.length) | ||
| throw (new Error('Unsuported ctf2json_version: ' + version)); | ||
| if (!('data' in json)) | ||
| throw (new Error('Invalid CTF JSON: missing data section')); | ||
| if (!Array.isArray(json['data'])) | ||
| throw (new Error('Malformed CTF JSON: data section is not ' + | ||
| 'an array')); | ||
| for (ii = 0; ii < json['data'].length; ii++) | ||
| ctfParseEntry(json['data'][ii], ctype); | ||
| } | ||
| exports.ctfParseJson = ctfParseJson; |
+129
| # | ||
| # Configuration File for JavaScript Lint 0.3.0 | ||
| # Developed by Matthias Miller (http://www.JavaScriptLint.com) | ||
| # | ||
| # This configuration file can be used to lint a collection of scripts, or to enable | ||
| # or disable warnings for scripts that are linted via the command line. | ||
| # | ||
| ### Warnings | ||
| # Enable or disable warnings based on requirements. | ||
| # Use "+WarningName" to display or "-WarningName" to suppress. | ||
| # | ||
| +no_return_value # function {0} does not always return a value | ||
| +duplicate_formal # duplicate formal argument {0} | ||
| +equal_as_assign # test for equality (==) mistyped as assignment (=)?{0} | ||
| +var_hides_arg # variable {0} hides argument | ||
| +redeclared_var # redeclaration of {0} {1} | ||
| +anon_no_return_value # anonymous function does not always return a value | ||
| +missing_semicolon # missing semicolon | ||
| +meaningless_block # meaningless block; curly braces have no impact | ||
| +comma_separated_stmts # multiple statements separated by commas (use semicolons?) | ||
| +unreachable_code # unreachable code | ||
| +missing_break # missing break statement | ||
| +missing_break_for_last_case # missing break statement for last case in switch | ||
| +comparison_type_conv # comparisons against null, 0, true, false, or an empty string allowing implicit type conversion (use === or !==) | ||
| -inc_dec_within_stmt # increment (++) and decrement (--) operators used as part of greater statement | ||
| +useless_void # use of the void type may be unnecessary (void is always undefined) | ||
| -useless_quotes # quotation marks are unnecessary | ||
| +multiple_plus_minus # unknown order of operations for successive plus (e.g. x+++y) or minus (e.g. x---y) signs | ||
| +use_of_label # use of label | ||
| -block_without_braces # block statement without curly braces | ||
| +leading_decimal_point # leading decimal point may indicate a number or an object member | ||
| +trailing_decimal_point # trailing decimal point may indicate a number or an object member | ||
| -octal_number # leading zeros make an octal number | ||
| +nested_comment # nested comment | ||
| +misplaced_regex # regular expressions should be preceded by a left parenthesis, assignment, colon, or comma | ||
| +ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement | ||
| +empty_statement # empty statement or extra semicolon | ||
| -missing_option_explicit # the "option explicit" control comment is missing | ||
| +partial_option_explicit # the "option explicit" control comment, if used, must be in the first script tag | ||
| +dup_option_explicit # duplicate "option explicit" control comment | ||
| +useless_assign # useless assignment | ||
| +ambiguous_nested_stmt # block statements containing block statements should use curly braces to resolve ambiguity | ||
| +ambiguous_else_stmt # the else statement could be matched with one of multiple if statements (use curly braces to indicate intent) | ||
| +missing_default_case # missing default case in switch statement | ||
| +duplicate_case_in_switch # duplicate case in switch statements | ||
| +default_not_at_end # the default case is not at the end of the switch statement | ||
| +legacy_cc_not_understood # couldn't understand control comment using /*@keyword@*/ syntax | ||
| +jsl_cc_not_understood # couldn't understand control comment using /*jsl:keyword*/ syntax | ||
| +useless_comparison # useless comparison; comparing identical expressions | ||
| +with_statement # with statement hides undeclared variables; use temporary variable instead | ||
| +trailing_comma_in_array # extra comma is not recommended in array initializers | ||
| +assign_to_function_call # assignment to a function call | ||
| +parseint_missing_radix # parseInt missing radix parameter | ||
| -unreferenced_argument # argument declared but never referenced: {name} | ||
| ### Output format | ||
| # Customize the format of the error message. | ||
| # __FILE__ indicates current file path | ||
| # __FILENAME__ indicates current file name | ||
| # __LINE__ indicates current line | ||
| # __ERROR__ indicates error message | ||
| # | ||
| # Visual Studio syntax (default): | ||
| +output-format __FILE__(__LINE__): __ERROR__ | ||
| # Alternative syntax: | ||
| #+output-format __FILE__:__LINE__: __ERROR__ | ||
| ### Context | ||
| # Show the in-line position of the error. | ||
| # Use "+context" to display or "-context" to suppress. | ||
| # | ||
| +context | ||
| ### Semicolons | ||
| # By default, assignments of an anonymous function to a variable or | ||
| # property (such as a function prototype) must be followed by a semicolon. | ||
| # | ||
| #+lambda_assign_requires_semicolon # deprecated setting | ||
| ### Control Comments | ||
| # Both JavaScript Lint and the JScript interpreter confuse each other with the syntax for | ||
| # the /*@keyword@*/ control comments and JScript conditional comments. (The latter is | ||
| # enabled in JScript with @cc_on@). The /*jsl:keyword*/ syntax is preferred for this reason, | ||
| # although legacy control comments are enabled by default for backward compatibility. | ||
| # | ||
| +legacy_control_comments | ||
| ### JScript Function Extensions | ||
| # JScript allows member functions to be defined like this: | ||
| # function MyObj() { /*constructor*/ } | ||
| # function MyObj.prototype.go() { /*member function*/ } | ||
| # | ||
| # It also allows events to be attached like this: | ||
| # function window::onload() { /*init page*/ } | ||
| # | ||
| # This is a Microsoft-only JavaScript extension. Enable this setting to allow them. | ||
| # | ||
| #-jscript_function_extensions # deprecated setting | ||
| ### Defining identifiers | ||
| # By default, "option explicit" is enabled on a per-file basis. | ||
| # To enable this for all files, use "+always_use_option_explicit" | ||
| -always_use_option_explicit | ||
| # Define certain identifiers of which the lint is not aware. | ||
| # (Use this in conjunction with the "undeclared identifier" warning.) | ||
| # | ||
| # Common uses for webpages might be: | ||
| #+define window | ||
| #+define document | ||
| +define require | ||
| +define exports | ||
| +define console | ||
| +define Buffer | ||
| +define JSON | ||
| ### Files | ||
| # Specify which files to lint | ||
| # Use "+recurse" to enable recursion (disabled by default). | ||
| # To add a set of files, use "+process FileName", "+process Folder\Path\*.js", | ||
| # or "+process Folder\Path\*.htm". | ||
| # | ||
| #+process jsl-test.js |
| { "metadata": | ||
| { | ||
| "ctf2json_version": "1.0", | ||
| "created_at": 1316563626, | ||
| "derived_from": "/lib/libc.so", | ||
| "ctf_version": 2, | ||
| "requested_types": [ "float" ] | ||
| }, | ||
| "data": | ||
| [ | ||
| { "name": "float", "float": { "length": 4 } } | ||
| ] | ||
| } |
| { "metadata": | ||
| { | ||
| "ctf2json_version": "1.0", | ||
| "created_at": 1316563631, | ||
| "derived_from": "/lib/libc.so", | ||
| "ctf_version": 2, | ||
| "requested_types": [ "int" ] | ||
| }, | ||
| "data": | ||
| [ | ||
| { "name": "int", "integer": { "length": 4, "signed": true } } | ||
| ] | ||
| } |
| { "metadata": | ||
| { | ||
| "ctf2json_version": "1.0", | ||
| "created_at": 1316563573, | ||
| "derived_from": "/lib/libc.so", | ||
| "ctf_version": 2, | ||
| "requested_types": [ "psinfo_t" ] | ||
| }, | ||
| "data": | ||
| [ | ||
| { "name": "int", "integer": { "length": 4, "signed": true } }, | ||
| { "name": "char", "integer": { "length": 1, "signed": true } }, | ||
| { "name": "unsigned short", "integer": { "length": 2, "signed": false } }, | ||
| { "name": "long", "integer": { "length": 4, "signed": true } }, | ||
| { "name": "unsigned", "integer": { "length": 4, "signed": false } }, | ||
| { "name": "size_t", "typedef": "unsigned" }, | ||
| { "name": "unsigned long", "integer": { "length": 4, "signed": false } }, | ||
| { "name": "time_t", "typedef": "long" }, | ||
| { "name": "struct timespec", "struct": [ | ||
| { "name": "tv_sec", "type": "time_t" }, | ||
| { "name": "tv_nsec", "type": "long" } | ||
| ] }, | ||
| { "name": "zoneid_t", "typedef": "long" }, | ||
| { "name": "taskid_t", "typedef": "long" }, | ||
| { "name": "dev_t", "typedef": "unsigned long" }, | ||
| { "name": "uid_t", "typedef": "unsigned" }, | ||
| { "name": "gid_t", "typedef": "unsigned" }, | ||
| { "name": "timestruc_t", "typedef": "struct timespec" }, | ||
| { "name": "short", "integer": { "length": 2, "signed": true } }, | ||
| { "name": "projid_t", "typedef": "long" }, | ||
| { "name": "ushort_t", "typedef": "unsigned short" }, | ||
| { "name": "poolid_t", "typedef": "long" }, | ||
| { "name": "uintptr_t", "typedef": "unsigned" }, | ||
| { "name": "id_t", "typedef": "long" }, | ||
| { "name": "pid_t", "typedef": "long" }, | ||
| { "name": "processorid_t", "typedef": "int" }, | ||
| { "name": "psetid_t", "typedef": "int" }, | ||
| { "name": "struct lwpsinfo", "struct": [ | ||
| { "name": "pr_flag", "type": "int" }, | ||
| { "name": "pr_lwpid", "type": "id_t" }, | ||
| { "name": "pr_addr", "type": "uintptr_t" }, | ||
| { "name": "pr_wchan", "type": "uintptr_t" }, | ||
| { "name": "pr_stype", "type": "char" }, | ||
| { "name": "pr_state", "type": "char" }, | ||
| { "name": "pr_sname", "type": "char" }, | ||
| { "name": "pr_nice", "type": "char" }, | ||
| { "name": "pr_syscall", "type": "short" }, | ||
| { "name": "pr_oldpri", "type": "char" }, | ||
| { "name": "pr_cpu", "type": "char" }, | ||
| { "name": "pr_pri", "type": "int" }, | ||
| { "name": "pr_pctcpu", "type": "ushort_t" }, | ||
| { "name": "pr_pad", "type": "ushort_t" }, | ||
| { "name": "pr_start", "type": "timestruc_t" }, | ||
| { "name": "pr_time", "type": "timestruc_t" }, | ||
| { "name": "pr_clname", "type": "char [8]" }, | ||
| { "name": "pr_name", "type": "char [16]" }, | ||
| { "name": "pr_onpro", "type": "processorid_t" }, | ||
| { "name": "pr_bindpro", "type": "processorid_t" }, | ||
| { "name": "pr_bindpset", "type": "psetid_t" }, | ||
| { "name": "pr_lgrp", "type": "int" }, | ||
| { "name": "pr_filler", "type": "int [4]" } | ||
| ] }, | ||
| { "name": "lwpsinfo_t", "typedef": "struct lwpsinfo" }, | ||
| { "name": "struct psinfo", "struct": [ | ||
| { "name": "pr_flag", "type": "int" }, | ||
| { "name": "pr_nlwp", "type": "int" }, | ||
| { "name": "pr_pid", "type": "pid_t" }, | ||
| { "name": "pr_ppid", "type": "pid_t" }, | ||
| { "name": "pr_pgid", "type": "pid_t" }, | ||
| { "name": "pr_sid", "type": "pid_t" }, | ||
| { "name": "pr_uid", "type": "uid_t" }, | ||
| { "name": "pr_euid", "type": "uid_t" }, | ||
| { "name": "pr_gid", "type": "gid_t" }, | ||
| { "name": "pr_egid", "type": "gid_t" }, | ||
| { "name": "pr_addr", "type": "uintptr_t" }, | ||
| { "name": "pr_size", "type": "size_t" }, | ||
| { "name": "pr_rssize", "type": "size_t" }, | ||
| { "name": "pr_pad1", "type": "size_t" }, | ||
| { "name": "pr_ttydev", "type": "dev_t" }, | ||
| { "name": "pr_pctcpu", "type": "ushort_t" }, | ||
| { "name": "pr_pctmem", "type": "ushort_t" }, | ||
| { "name": "pr_start", "type": "timestruc_t" }, | ||
| { "name": "pr_time", "type": "timestruc_t" }, | ||
| { "name": "pr_ctime", "type": "timestruc_t" }, | ||
| { "name": "pr_fname", "type": "char [16]" }, | ||
| { "name": "pr_psargs", "type": "char [80]" }, | ||
| { "name": "pr_wstat", "type": "int" }, | ||
| { "name": "pr_argc", "type": "int" }, | ||
| { "name": "pr_argv", "type": "uintptr_t" }, | ||
| { "name": "pr_envp", "type": "uintptr_t" }, | ||
| { "name": "pr_dmodel", "type": "char" }, | ||
| { "name": "pr_pad2", "type": "char [3]" }, | ||
| { "name": "pr_taskid", "type": "taskid_t" }, | ||
| { "name": "pr_projid", "type": "projid_t" }, | ||
| { "name": "pr_nzomb", "type": "int" }, | ||
| { "name": "pr_poolid", "type": "poolid_t" }, | ||
| { "name": "pr_zoneid", "type": "zoneid_t" }, | ||
| { "name": "pr_contract", "type": "id_t" }, | ||
| { "name": "pr_filler", "type": "int [1]" }, | ||
| { "name": "pr_lwp", "type": "lwpsinfo_t" } | ||
| ] }, | ||
| { "name": "psinfo_t", "typedef": "struct psinfo" } | ||
| ] | ||
| } |
| { "metadata": | ||
| { | ||
| "ctf2json_version": "1.0", | ||
| "created_at": 1316563648, | ||
| "derived_from": "/lib/libc.so", | ||
| "ctf_version": 2, | ||
| "requested_types": [ "timestruc_t" ] | ||
| }, | ||
| "data": | ||
| [ | ||
| { "name": "long", "integer": { "length": 4, "signed": true } }, | ||
| { "name": "time_t", "typedef": "long" }, | ||
| { "name": "struct timespec", "struct": [ | ||
| { "name": "tv_sec", "type": "time_t" }, | ||
| { "name": "tv_nsec", "type": "long" } | ||
| ] }, | ||
| { "name": "timestruc_t", "typedef": "struct timespec" } | ||
| ] | ||
| } |
| /* | ||
| * Test several conditions that should always cause us to throw. | ||
| */ | ||
| var mod_assert = require('assert'); | ||
| var mod_ctype = require('../../ctype.js'); | ||
| var cases = [ | ||
| { json: { }, msg: 'bad JSON - no metadata or data' }, | ||
| { json: { metadata: {} }, msg: 'bad JSON - bad metadata section' }, | ||
| { json: { metadata: { 'JSON version': [] } }, | ||
| msg: 'bad JSON - bad JSON version' }, | ||
| { json: { metadata: { 'JSON version': 2 } }, | ||
| msg: 'bad JSON - bad JSON version' }, | ||
| { json: { metadata: { 'JSON version': '100.20' } }, | ||
| msg: 'bad JSON - bad JSON version' }, | ||
| { json: { metadata: { 'JSON version': '1.0' } }, | ||
| msg: 'missing data section' }, | ||
| { json: { metadata: { 'JSON version': '1.0' }, data: 1 }, | ||
| msg: 'invalid data section' }, | ||
| { json: { metadata: { 'JSON version': '1.0' }, data: 1.1 }, | ||
| msg: 'invalid data section' }, | ||
| { json: { metadata: { 'JSON version': '1.0' }, data: '1.1' }, | ||
| msg: 'invalid data section' }, | ||
| { json: { metadata: { 'JSON version': '1.0' }, data: {} }, | ||
| msg: 'invalid data section' } | ||
| ]; | ||
| function test() | ||
| { | ||
| var ii; | ||
| for (ii = 0; ii < cases.length; ii++) { | ||
| mod_assert.throws(function () { | ||
| mod_ctype.parseCTF(cases[ii].json); | ||
| }, Error, cases[ii].msg); | ||
| } | ||
| } | ||
| test(); |
| var mod_fs = require('fs'); | ||
| var mod_ctype = require('../../ctype.js'); | ||
| var mod_assert = require('assert'); | ||
| function test() | ||
| { | ||
| var data, parser; | ||
| data = JSON.parse(mod_fs.readFileSync('./float.json').toString()); | ||
| parser = mod_ctype.parseCTF(data, { endian: 'big' }); | ||
| mod_assert.deepEqual(parser.lstypes(), {}); | ||
| } | ||
| test(); |
| var mod_fs = require('fs'); | ||
| var mod_ctype = require('../../ctype.js'); | ||
| var mod_assert = require('assert'); | ||
| function test() | ||
| { | ||
| var data, parser; | ||
| data = JSON.parse(mod_fs.readFileSync('./int.json').toString()); | ||
| parser = mod_ctype.parseCTF(data, { endian: 'big' }); | ||
| mod_assert.deepEqual(parser.lstypes(), { 'int': 'uint32_t' }); | ||
| } | ||
| test(); |
| var mod_fs = require('fs'); | ||
| var mod_ctype = require('../../ctype.js'); | ||
| var mod_assert = require('assert'); | ||
| /* | ||
| * This is too unwieldly to actually write out. Just make sure we can parse it | ||
| * without errrors. | ||
| */ | ||
| function test() | ||
| { | ||
| var data; | ||
| data = JSON.parse(mod_fs.readFileSync('./psinfo.json').toString()); | ||
| mod_ctype.parseCTF(data, { endian: 'big' }); | ||
| } | ||
| test(); |
| var mod_fs = require('fs'); | ||
| var mod_ctype = require('../../ctype.js'); | ||
| var mod_assert = require('assert'); | ||
| function test() | ||
| { | ||
| var data, parser; | ||
| data = JSON.parse(mod_fs.readFileSync('./struct.json').toString()); | ||
| parser = mod_ctype.parseCTF(data, { endian: 'big' }); | ||
| mod_assert.deepEqual(parser.lstypes(), { 'long': 'uint32_t', | ||
| 'time_t': 'long', | ||
| 'timestruc_t': 'struct timespec', | ||
| 'struct timespec': [ { 'tv_sec': { 'type': 'time_t' } }, | ||
| { 'tv_nsec': { 'type': 'long' } } ] }); | ||
| } | ||
| test(); |
| var mod_fs = require('fs'); | ||
| var mod_ctype = require('../../ctype.js'); | ||
| var mod_assert = require('assert'); | ||
| function test() | ||
| { | ||
| var data, parser; | ||
| data = JSON.parse(mod_fs.readFileSync('./typedef.json').toString()); | ||
| parser = mod_ctype.parseCTF(data, { endian: 'big' }); | ||
| mod_assert.deepEqual(parser.lstypes(), { 'bar_t': 'int', | ||
| 'int': 'uint32_t' }); | ||
| } | ||
| test(); |
| { "metadata": | ||
| { | ||
| "ctf2json_version": "1.0", | ||
| "created_at": 1316302348, | ||
| "derived_from": "/lib/libc.so", | ||
| "ctf_version": 2, | ||
| "requested_types": [ "bar_t" ] | ||
| }, | ||
| "data": | ||
| [ | ||
| { "name": "int", "integer": { "length": 4, "signed": true } }, | ||
| { "name": "bar_t", "typedef": "int" } | ||
| ] | ||
| } |
+6
-0
@@ -7,2 +7,8 @@ This contains tickets fixed in each version release in reverse chronological | ||
| v0.2.0: | ||
| CTYPE-23 Release v0.2.0 | ||
| CTYPE-21 Add support for CTF JSON data | ||
| CTYPE-22 Add Javascriptlint profile | ||
| CTYPE-15 Pull in ctio updates from node/master | ||
| v0.1.0: | ||
@@ -9,0 +15,0 @@ CTYPE-18 Bump version to v0.1.0 |
+97
-83
@@ -67,6 +67,20 @@ /* | ||
| */ | ||
| function ruint16(buffer, endian, offset) | ||
| function rgint16(buffer, endian, offset) | ||
| { | ||
| var val = 0; | ||
| if (endian == 'big') { | ||
| val = buffer[offset] << 8; | ||
| val |= buffer[offset+1]; | ||
| } else { | ||
| val = buffer[offset]; | ||
| val |= buffer[offset+1] << 8; | ||
| } | ||
| return (val); | ||
| } | ||
| function ruint16(buffer, endian, offset) | ||
| { | ||
| if (endian === undefined) | ||
@@ -84,11 +98,3 @@ throw (new Error('missing endian')); | ||
| if (endian == 'big') { | ||
| val = buffer[offset] << 8; | ||
| val |= buffer[offset+1]; | ||
| } else { | ||
| val = buffer[offset]; | ||
| val |= buffer[offset+1] << 8; | ||
| } | ||
| return (val); | ||
| return (rgint16(buffer, endian, offset)); | ||
| } | ||
@@ -107,9 +113,19 @@ | ||
| */ | ||
| function rgint32(buffer, endian, offset) | ||
| { | ||
| var val = 0; | ||
| /* | ||
| * Handle the case of losing our MSBit | ||
| */ | ||
| function fixu32(upper, lower) | ||
| { | ||
| return ((upper * (1 << 24)) + lower); | ||
| if (endian == 'big') { | ||
| val = buffer[offset+1] << 16; | ||
| val |= buffer[offset+2] << 8; | ||
| val |= buffer[offset+3]; | ||
| val = val + (buffer[offset] << 24 >>> 0); | ||
| } else { | ||
| val = buffer[offset+2] << 16; | ||
| val |= buffer[offset+1] << 8; | ||
| val |= buffer[offset]; | ||
| val = val + (buffer[offset + 3] << 24 >>> 0); | ||
| } | ||
| return (val); | ||
| } | ||
@@ -119,4 +135,2 @@ | ||
| { | ||
| var val = 0; | ||
| if (endian === undefined) | ||
@@ -134,15 +148,3 @@ throw (new Error('missing endian')); | ||
| if (endian == 'big') { | ||
| val = buffer[offset+1] << 16; | ||
| val |= buffer[offset+2] << 8; | ||
| val |= buffer[offset+3]; | ||
| val = fixu32(buffer[offset], val); | ||
| } else { | ||
| val = buffer[offset+2] << 16; | ||
| val |= buffer[offset+1] << 8; | ||
| val |= buffer[offset]; | ||
| val = fixu32(buffer[offset+3], val); | ||
| } | ||
| return (val); | ||
| return (rgint32(buffer, endian, offset)); | ||
| } | ||
@@ -166,6 +168,19 @@ | ||
| */ | ||
| function ruint64(buffer, endian, offset) | ||
| function rgint64(buffer, endian, offset) | ||
| { | ||
| var val = new Array(2); | ||
| if (endian == 'big') { | ||
| val[0] = ruint32(buffer, endian, offset); | ||
| val[1] = ruint32(buffer, endian, offset+4); | ||
| } else { | ||
| val[0] = ruint32(buffer, endian, offset+4); | ||
| val[1] = ruint32(buffer, endian, offset); | ||
| } | ||
| return (val); | ||
| } | ||
| function ruint64(buffer, endian, offset) | ||
| { | ||
| if (endian === undefined) | ||
@@ -183,11 +198,3 @@ throw (new Error('missing endian')); | ||
| if (endian == 'big') { | ||
| val[0] = ruint32(buffer, endian, offset); | ||
| val[1] = ruint32(buffer, endian, offset+4); | ||
| } else { | ||
| val[0] = ruint32(buffer, endian, offset+4); | ||
| val[1] = ruint32(buffer, endian, offset); | ||
| } | ||
| return (val); | ||
| return (rgint64(buffer, endian, offset)); | ||
| } | ||
@@ -294,3 +301,3 @@ | ||
| val = ruint16(buffer, endian, offset); | ||
| val = rgint16(buffer, endian, offset); | ||
| neg = val & 0x8000; | ||
@@ -327,3 +334,3 @@ if (!neg) | ||
| val = ruint32(buffer, endian, offset); | ||
| val = rgint32(buffer, endian, offset); | ||
| neg = val & 0x80000000; | ||
@@ -356,3 +363,3 @@ if (!neg) | ||
| val = ruint64(buffer, endian, offset); | ||
| val = rgint64(buffer, endian, offset); | ||
| neg = val[0] & 0x80000000; | ||
@@ -710,2 +717,13 @@ | ||
| */ | ||
| function wgint16(val, endian, buffer, offset) | ||
| { | ||
| if (endian == 'big') { | ||
| buffer[offset] = (val & 0xff00) >>> 8; | ||
| buffer[offset+1] = val & 0x00ff; | ||
| } else { | ||
| buffer[offset+1] = (val & 0xff00) >>> 8; | ||
| buffer[offset] = val & 0x00ff; | ||
| } | ||
| } | ||
| function wuint16(value, endian, buffer, offset) | ||
@@ -731,9 +749,3 @@ { | ||
| val = prepuint(value, 0xffff); | ||
| if (endian == 'big') { | ||
| buffer[offset] = (val & 0xff00) >>> 8; | ||
| buffer[offset+1] = val & 0x00ff; | ||
| } else { | ||
| buffer[offset+1] = (val & 0xff00) >>> 8; | ||
| buffer[offset] = val & 0x00ff; | ||
| } | ||
| wgint16(val, endian, buffer, offset); | ||
| } | ||
@@ -752,2 +764,18 @@ | ||
| */ | ||
| function wgint32(val, endian, buffer, offset) | ||
| { | ||
| if (endian == 'big') { | ||
| buffer[offset] = (val - (val & 0x00ffffff)) / Math.pow(2, 24); | ||
| buffer[offset+1] = (val >>> 16) & 0xff; | ||
| buffer[offset+2] = (val >>> 8) & 0xff; | ||
| buffer[offset+3] = val & 0xff; | ||
| } else { | ||
| buffer[offset+3] = (val - (val & 0x00ffffff)) / | ||
| Math.pow(2, 24); | ||
| buffer[offset+2] = (val >>> 16) & 0xff; | ||
| buffer[offset+1] = (val >>> 8) & 0xff; | ||
| buffer[offset] = val & 0xff; | ||
| } | ||
| } | ||
| function wuint32(value, endian, buffer, offset) | ||
@@ -773,14 +801,3 @@ { | ||
| val = prepuint(value, 0xffffffff); | ||
| if (endian == 'big') { | ||
| buffer[offset] = (val - (val & 0x00ffffff)) / Math.pow(2, 24); | ||
| buffer[offset+1] = (val >>> 16) & 0xff; | ||
| buffer[offset+2] = (val >>> 8) & 0xff; | ||
| buffer[offset+3] = val & 0xff; | ||
| } else { | ||
| buffer[offset+3] = (val - (val & 0x00ffffff)) / | ||
| Math.pow(2, 24); | ||
| buffer[offset+2] = (val >>> 16) & 0xff; | ||
| buffer[offset+1] = (val >>> 8) & 0xff; | ||
| buffer[offset] = val & 0xff; | ||
| } | ||
| wgint32(val, endian, buffer, offset); | ||
| } | ||
@@ -793,2 +810,13 @@ | ||
| */ | ||
| function wgint64(value, endian, buffer, offset) | ||
| { | ||
| if (endian == 'big') { | ||
| wgint32(value[0], endian, buffer, offset); | ||
| wgint32(value[1], endian, buffer, offset+4); | ||
| } else { | ||
| wgint32(value[0], endian, buffer, offset+4); | ||
| wgint32(value[1], endian, buffer, offset); | ||
| } | ||
| } | ||
| function wuint64(value, endian, buffer, offset) | ||
@@ -819,10 +847,3 @@ { | ||
| prepuint(value[1], 0xffffffff); | ||
| if (endian == 'big') { | ||
| wuint32(value[0], endian, buffer, offset); | ||
| wuint32(value[1], endian, buffer, offset+4); | ||
| } else { | ||
| wuint32(value[0], endian, buffer, offset+4); | ||
| wuint32(value[1], endian, buffer, offset); | ||
| } | ||
| wgint64(value, endian, buffer, offset); | ||
| } | ||
@@ -948,5 +969,5 @@ | ||
| if (val >= 0) | ||
| wuint16(val, endian, buffer, offset); | ||
| wgint16(val, endian, buffer, offset); | ||
| else | ||
| wuint16(0xffff + val + 1, endian, buffer, offset); | ||
| wgint16(0xffff + val + 1, endian, buffer, offset); | ||
@@ -980,5 +1001,5 @@ } | ||
| if (val >= 0) | ||
| wuint32(val, endian, buffer, offset); | ||
| wgint32(val, endian, buffer, offset); | ||
| else | ||
| wuint32(0xffffffff + val + 1, endian, buffer, offset); | ||
| wgint32(0xffffffff + val + 1, endian, buffer, offset); | ||
| } | ||
@@ -1031,10 +1052,3 @@ | ||
| } | ||
| if (endian == 'big') { | ||
| wuint32(vals[0], endian, buffer, offset); | ||
| wuint32(vals[1], endian, buffer, offset+4); | ||
| } else { | ||
| wuint32(vals[0], endian, buffer, offset+4); | ||
| wuint32(vals[1], endian, buffer, offset); | ||
| } | ||
| wgint64(vals, endian, buffer, offset); | ||
| } | ||
@@ -1041,0 +1055,0 @@ |
+12
-2
@@ -37,2 +37,3 @@ /* | ||
| var mod_ctf = require('./ctf.js'); | ||
| var mod_ctio = require('./ctio.js'); | ||
@@ -283,3 +284,3 @@ var ASSERT = require('assert'); | ||
| var ii, jj; | ||
| var req, keys, key, exists; | ||
| var req, keys, key; | ||
| var found = {}; | ||
@@ -321,3 +322,2 @@ | ||
| if (isNaN(parseInt(key['len'], 10))) { | ||
| exists = false; | ||
| if (!(key['len'] in found)) | ||
@@ -823,2 +823,10 @@ throw (new Error('Given an array ' + | ||
| function parseCTF(json, conf) | ||
| { | ||
| var ctype = new CTypeParser(conf); | ||
| mod_ctf.ctfParseJson(json, ctype); | ||
| return (ctype); | ||
| } | ||
| /* | ||
@@ -832,2 +840,4 @@ * Export the few things we actually want to. Currently this is just the CType | ||
| exports.parseCTF = parseCTF; | ||
| exports.ruint8 = mod_ctio.ruint8; | ||
@@ -834,0 +844,0 @@ exports.ruint16 = mod_ctio.ruint16; |
+2
-2
| { | ||
| "name": "ctype", | ||
| "version": "0.1.0", | ||
| "version": "0.2.0", | ||
| "description": "read and write binary structures and data types", | ||
| "homepage": "https://github.com/rmustacc/node-ctype", | ||
| "author": "Robert Mustacchi <rm@fingolfin.org>", | ||
| "engines": { "node": "0.4" }, | ||
| "engines": { "node": "0.4 || 0.5" }, | ||
| "main": "ctype.js" | ||
| } |
+23
-3
@@ -103,6 +103,6 @@ This library provides a way to read and write binary data. | ||
| The set of defined types can be printed with lsdef. The format of this output | ||
| The set of defined types can be printed with lstypes. The format of this output | ||
| is subject to change, but likely will look something like: | ||
| > lsdef(); | ||
| > lstypes(); | ||
| { | ||
@@ -153,2 +153,10 @@ size_t: 'uint32_t', | ||
| CTF JSON data: | ||
| node-ctype can also handle JSON data that mathces the format described in the | ||
| documentation of the tool ctf2json. Given the JSON data which specifies type | ||
| information, it will transform that into a parser that understands all of the | ||
| types defined inside of it. This is useful for more complicated structures that | ||
| have a lot of typedefs. | ||
| Interface overview | ||
@@ -169,2 +177,14 @@ | ||
| /* | ||
| * Parses the CTF JSON data and creates a parser that understands all of those | ||
| * types. | ||
| * | ||
| * data Parsed JSON data that maches that CTF JSON | ||
| * specification. | ||
| * | ||
| * conf The configuration object to create a new CTypeParser | ||
| * from. | ||
| */ | ||
| CTypeParser parseCTF(data, conf); | ||
| /* | ||
| * This is what we were born to do. We read the data from a buffer and return it | ||
@@ -208,3 +228,3 @@ * in an object whose keys match the values from the object. | ||
| Object CTypeParser.prototype.lsdef(); | ||
| Object CTypeParser.prototype.lstypes(); | ||
@@ -211,0 +231,0 @@ /* |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
175672
14.47%29
81.25%4300
12.57%299
7.17%9
125%