Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit a72be7746fdb8eac063ce6dcab97cdecbc07127c 0 parents
Brian White authored

Showing 4 changed files with 172 additions and 0 deletions. Show diff stats Hide diff stats

  1. +19 0 LICENSE
  2. +70 0 README.md
  3. +73 0 groan.js
  4. +10 0 package.json
19 LICENSE
... ... @@ -0,0 +1,19 @@
  1 +Copyright Brian White. All rights reserved.
  2 +
  3 +Permission is hereby granted, free of charge, to any person obtaining a copy
  4 +of this software and associated documentation files (the "Software"), to
  5 +deal in the Software without restriction, including without limitation the
  6 +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  7 +sell copies of the Software, and to permit persons to whom the Software is
  8 +furnished to do so, subject to the following conditions:
  9 +
  10 +The above copyright notice and this permission notice shall be included in
  11 +all copies or substantial portions of the Software.
  12 +
  13 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18 +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  19 +IN THE SOFTWARE.
70 README.md
Source Rendered
... ... @@ -0,0 +1,70 @@
  1 +Description
  2 +===========
  3 +
  4 +groan is a PHP session file parser written in JavaScript.
  5 +
  6 +
  7 +Requirements
  8 +============
  9 +
  10 +* JavaScript (compatible with [node.js](http://nodejs.org/))
  11 +
  12 +
  13 +Node.JS Example
  14 +===============
  15 +
  16 +```javascript
  17 +var fs = require('fs'),
  18 + parser = require('groan');
  19 +
  20 +/*
  21 + ideally you should first ensure (session file's
  22 + mtime + PHP's session.gc_maxlifetime) > Date.now() to ensure that the
  23 + session has not expired yet
  24 +*/
  25 +
  26 +// if it is still valid, continue on ...
  27 +fs.readFile('/tmp/sess_1234567890abcdef', function(err, b) {
  28 + if (err) throw err;
  29 + console.dir(parser(b.toString('utf8')));
  30 + /*
  31 + for a $_SESSION that contains:
  32 + ["a"]=>
  33 + string(5) "apple"
  34 + ["b"]=>
  35 + bool(false)
  36 + ["c"]=>
  37 + array(3) {
  38 + [0]=>
  39 + int(17)
  40 + [1]=>
  41 + float(1.5)
  42 + [2]=>
  43 + string(1) "x"
  44 + }
  45 + ["d"]=>
  46 + array(0) {
  47 + }
  48 +
  49 + the parser will return an object that looks like:
  50 + {
  51 + a: 'apple',
  52 + b: false,
  53 + c: {
  54 + 0: 17,
  55 + 1: 1.5,
  56 + 2: 'x'
  57 + },
  58 + d: {}
  59 + }
  60 + */
  61 +});
  62 +```
  63 +
  64 +
  65 +Notes
  66 +=====
  67 +
  68 +* References and recursion are not currently supported (currently returns `undefined`)
  69 +
  70 +* The parser assumes the session file data is in the valid PHP session serialized format
73 groan.js
... ... @@ -0,0 +1,73 @@
  1 +function PHParse(str) {
  2 + var result = {}, o = { str: str, pos: 0 };
  3 + for (var k,v,i,last=o.str.length; o.pos<last;) {
  4 + i = o.str.indexOf('|', o.pos);
  5 + k = o.str.substring(o.pos, i);
  6 + o.pos = i + 1;
  7 + v = __PHParseValue(o);
  8 + result[k] = v;
  9 + }
  10 + return result;
  11 +};
  12 +var __PHParseValue = function(o) {
  13 + var v, type = o.str[o.pos].toLowerCase(), len, idelim;
  14 + o.pos += 2;
  15 + if (type === 's') {
  16 + idelim = o.str.indexOf(':', o.pos);
  17 + len = parseInt(o.str.substring(o.pos, idelim), 10);
  18 + o.pos = idelim + 2;
  19 + v = __PHParseString(o);
  20 + } else if (type === 'i') {
  21 + idelim = o.str.indexOf(';', o.pos);
  22 + v = parseInt(o.str.substring(o.pos, idelim), 10);
  23 + o.pos = idelim + 1;
  24 + } else if (type === 'd') {
  25 + idelim = o.str.indexOf(';', o.pos);
  26 + v = parseFloat(o.str.substring(o.pos, idelim), 10);
  27 + o.pos = idelim + 1;
  28 + } else if (type === 'b') {
  29 + v = (o.str[o.pos] === '1');
  30 + o.pos += 2;
  31 + } else if (type === 'a' || type === 'o') {
  32 + v = {};
  33 + if (type === 'o') {
  34 + // skip object class name
  35 + o.pos = o.str.indexOf(':', o.pos) + 2;
  36 + __PHParseString(o);
  37 + }
  38 + idelim = o.str.indexOf(':', o.pos);
  39 + len = parseInt(o.str.substring(o.pos, idelim), 10);
  40 + o.pos = idelim + 2;
  41 + for (var i=0,key,val; i<len; ++i) {
  42 + v[__PHParseValue(o)] = __PHParseValue(o);
  43 + /*key = __PHParseValue(o);
  44 + val = __PHParseValue(o);
  45 + v[key] = val;*/
  46 + }
  47 + ++o.pos;
  48 + } else if (type === 'r') {
  49 + // TODO: support for recursion/references
  50 + o.pos = o.str.indexOf(';', o.pos) + 1;
  51 + v = undefined;
  52 + } else if (type === 'n')
  53 + v = null;
  54 + return v;
  55 +};
  56 +var __PHParseString = function(o) {
  57 + var s = "", orig = o.pos, escaped = false;
  58 + while (true) {
  59 + if (o.str[o.pos] === '"' && !escaped) {
  60 + s = o.str.substring(orig, o.pos);
  61 + break;
  62 + } else if (o.str[o.pos] === '\\')
  63 + escaped = !escaped;
  64 + ++o.pos;
  65 + }
  66 + o.pos += 2;
  67 + return s;
  68 +};
  69 +
  70 +if (module)
  71 + module.exports = PHParse;
  72 +else if (window)
  73 + window.PHParse = PHParse;
10 package.json
... ... @@ -0,0 +1,10 @@
  1 +{ "name": "groan",
  2 + "version": "0.0.1",
  3 + "author": "Brian White <mscdex@mscdex.net>",
  4 + "description": "A PHP session file parser written in JavaScript",
  5 + "main": "./groan",
  6 + "engines": { "node" : ">=0.2.0" },
  7 + "keywords": [ "php", "session", "parser" ],
  8 + "licenses": [ { "type": "MIT", "url": "http://github.com/mscdex/groan/raw/master/LICENSE" } ],
  9 + "repository" : { "type": "git", "url": "http://github.com/mscdex/groan.git" }
  10 +}

0 comments on commit a72be77

Please sign in to comment.
Something went wrong with that request. Please try again.