Issues (101)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

js/vendor/pdfjs/web/debugger.js (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
/* Copyright 2012 Mozilla Foundation
2
 *
3
 * Licensed under the Apache License, Version 2.0 (the "License");
4
 * you may not use this file except in compliance with the License.
5
 * You may obtain a copy of the License at
6
 *
7
 *     http://www.apache.org/licenses/LICENSE-2.0
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 */
15
16
'use strict';
0 ignored issues
show
Use the function form of "use strict".
Loading history...
17
18
var FontInspector = (function FontInspectorClosure() {
19
  var fonts;
20
  var active = false;
21
  var fontAttribute = 'data-font-name';
22
  function removeSelection() {
23
    var divs = document.querySelectorAll('div[' + fontAttribute + ']');
24
    for (var i = 0, ii = divs.length; i < ii; ++i) {
25
      var div = divs[i];
26
      div.className = '';
27
    }
28
  }
29
  function resetSelection() {
30
    var divs = document.querySelectorAll('div[' + fontAttribute + ']');
31
    for (var i = 0, ii = divs.length; i < ii; ++i) {
32
      var div = divs[i];
33
      div.className = 'debuggerHideText';
34
    }
35
  }
36
  function selectFont(fontName, show) {
37
    var divs = document.querySelectorAll('div[' + fontAttribute + '=' +
38
                                         fontName + ']');
39
    for (var i = 0, ii = divs.length; i < ii; ++i) {
40
      var div = divs[i];
41
      div.className = show ? 'debuggerShowText' : 'debuggerHideText';
42
    }
43
  }
44
  function textLayerClick(e) {
45
    if (!e.target.dataset.fontName ||
46
        e.target.tagName.toUpperCase() !== 'DIV') {
47
      return;
48
    }
49
    var fontName = e.target.dataset.fontName;
50
    var selects = document.getElementsByTagName('input');
51
    for (var i = 0; i < selects.length; ++i) {
52
      var select = selects[i];
53
      if (select.dataset.fontName !== fontName) {
54
        continue;
55
      }
56
      select.checked = !select.checked;
57
      selectFont(fontName, select.checked);
58
      select.scrollIntoView();
59
    }
60
  }
61
  return {
62
    // Properties/functions needed by PDFBug.
63
    id: 'FontInspector',
64
    name: 'Font Inspector',
65
    panel: null,
66
    manager: null,
67
    init: function init(pdfjsLib) {
68
      var panel = this.panel;
69
      panel.setAttribute('style', 'padding: 5px;');
70
      var tmp = document.createElement('button');
71
      tmp.addEventListener('click', resetSelection);
72
      tmp.textContent = 'Refresh';
73
      panel.appendChild(tmp);
74
75
      fonts = document.createElement('div');
76
      panel.appendChild(fonts);
77
    },
78
    cleanup: function cleanup() {
79
      fonts.textContent = '';
80
    },
81
    enabled: false,
82
    get active() {
83
      return active;
84
    },
85
    set active(value) {
86
      active = value;
87
      if (active) {
88
        document.body.addEventListener('click', textLayerClick, true);
89
        resetSelection();
90
      } else {
91
        document.body.removeEventListener('click', textLayerClick, true);
92
        removeSelection();
93
      }
94
    },
95
    // FontInspector specific functions.
96
    fontAdded: function fontAdded(fontObj, url) {
97
      function properties(obj, list) {
98
        var moreInfo = document.createElement('table');
99
        for (var i = 0; i < list.length; i++) {
100
          var tr = document.createElement('tr');
101
          var td1 = document.createElement('td');
102
          td1.textContent = list[i];
103
          tr.appendChild(td1);
104
          var td2 = document.createElement('td');
105
          td2.textContent = obj[list[i]].toString();
106
          tr.appendChild(td2);
107
          moreInfo.appendChild(tr);
108
        }
109
        return moreInfo;
110
      }
111
      var moreInfo = properties(fontObj, ['name', 'type']);
112
      var fontName = fontObj.loadedName;
113
      var font = document.createElement('div');
114
      var name = document.createElement('span');
115
      name.textContent = fontName;
116
      var download = document.createElement('a');
117
      if (url) {
118
        url = /url\(['"]?([^\)"']+)/.exec(url);
119
        download.href = url[1];
120
      } else if (fontObj.data) {
121
        url = URL.createObjectURL(new Blob([fontObj.data], {
122
          type: fontObj.mimeType,
123
        }));
124
        download.href = url;
125
      }
126
      download.textContent = 'Download';
127
      var logIt = document.createElement('a');
128
      logIt.href = '';
129
      logIt.textContent = 'Log';
130
      logIt.addEventListener('click', function(event) {
131
        event.preventDefault();
132
        console.log(fontObj);
133
      });
134
      var select = document.createElement('input');
135
      select.setAttribute('type', 'checkbox');
136
      select.dataset.fontName = fontName;
137
      select.addEventListener('click', (function(select, fontName) {
138
        return (function() {
139
           selectFont(fontName, select.checked);
140
        });
141
      })(select, fontName));
142
      font.appendChild(select);
143
      font.appendChild(name);
144
      font.appendChild(document.createTextNode(' '));
145
      font.appendChild(download);
146
      font.appendChild(document.createTextNode(' '));
147
      font.appendChild(logIt);
148
      font.appendChild(moreInfo);
149
      fonts.appendChild(font);
150
      // Somewhat of a hack, should probably add a hook for when the text layer
151
      // is done rendering.
152
      setTimeout(() => {
0 ignored issues
show
'arrow function syntax (=>)' is only available in ES6 (use 'esversion: 6').

Generally using ECMAScript 6 specific syntax is fine if you are sure that it is already supported by all engines which are supposed to run this code.

Further Reading:

Loading history...
153
        if (this.active) {
154
          resetSelection();
155
        }
156
      }, 2000);
157
    },
158
  };
159
})();
160
161
var opMap;
162
163
// Manages all the page steppers.
164
var StepperManager = (function StepperManagerClosure() {
165
  var steppers = [];
166
  var stepperDiv = null;
167
  var stepperControls = null;
168
  var stepperChooser = null;
169
  var breakPoints = Object.create(null);
170
  return {
171
    // Properties/functions needed by PDFBug.
172
    id: 'Stepper',
173
    name: 'Stepper',
174
    panel: null,
175
    manager: null,
176
    init: function init(pdfjsLib) {
177
      var self = this;
178
      this.panel.setAttribute('style', 'padding: 5px;');
179
      stepperControls = document.createElement('div');
180
      stepperChooser = document.createElement('select');
181
      stepperChooser.addEventListener('change', function(event) {
182
        self.selectStepper(this.value);
183
      });
184
      stepperControls.appendChild(stepperChooser);
185
      stepperDiv = document.createElement('div');
186
      this.panel.appendChild(stepperControls);
187
      this.panel.appendChild(stepperDiv);
188
      if (sessionStorage.getItem('pdfjsBreakPoints')) {
189
        breakPoints = JSON.parse(sessionStorage.getItem('pdfjsBreakPoints'));
190
      }
191
192
      opMap = Object.create(null);
193
      for (var key in pdfjsLib.OPS) {
194
        opMap[pdfjsLib.OPS[key]] = key;
195
      }
196
    },
197
    cleanup: function cleanup() {
198
      stepperChooser.textContent = '';
199
      stepperDiv.textContent = '';
200
      steppers = [];
201
    },
202
    enabled: false,
203
    active: false,
204
    // Stepper specific functions.
205
    create: function create(pageIndex) {
206
      var debug = document.createElement('div');
207
      debug.id = 'stepper' + pageIndex;
208
      debug.setAttribute('hidden', true);
209
      debug.className = 'stepper';
210
      stepperDiv.appendChild(debug);
211
      var b = document.createElement('option');
212
      b.textContent = 'Page ' + (pageIndex + 1);
213
      b.value = pageIndex;
214
      stepperChooser.appendChild(b);
215
      var initBreakPoints = breakPoints[pageIndex] || [];
216
      var stepper = new Stepper(debug, pageIndex, initBreakPoints);
217
      steppers.push(stepper);
218
      if (steppers.length === 1) {
219
        this.selectStepper(pageIndex, false);
220
      }
221
      return stepper;
222
    },
223
    selectStepper: function selectStepper(pageIndex, selectPanel) {
224
      var i;
225
      pageIndex = pageIndex | 0;
226
      if (selectPanel) {
227
        this.manager.selectPanel(this);
228
      }
229
      for (i = 0; i < steppers.length; ++i) {
230
        var stepper = steppers[i];
231
        if (stepper.pageIndex === pageIndex) {
232
          stepper.panel.removeAttribute('hidden');
233
        } else {
234
          stepper.panel.setAttribute('hidden', true);
235
        }
236
      }
237
      var options = stepperChooser.options;
238
      for (i = 0; i < options.length; ++i) {
239
        var option = options[i];
240
        option.selected = (option.value | 0) === pageIndex;
241
      }
242
    },
243
    saveBreakPoints: function saveBreakPoints(pageIndex, bps) {
244
      breakPoints[pageIndex] = bps;
245
      sessionStorage.setItem('pdfjsBreakPoints', JSON.stringify(breakPoints));
246
    },
247
  };
248
})();
249
250
// The stepper for each page's IRQueue.
251
var Stepper = (function StepperClosure() {
252
  // Shorter way to create element and optionally set textContent.
253
  function c(tag, textContent) {
254
    var d = document.createElement(tag);
255
    if (textContent) {
256
      d.textContent = textContent;
257
    }
258
    return d;
259
  }
260
261
  function simplifyArgs(args) {
262
    if (typeof args === 'string') {
263
      var MAX_STRING_LENGTH = 75;
264
      return args.length <= MAX_STRING_LENGTH ? args :
265
        args.substr(0, MAX_STRING_LENGTH) + '...';
266
    }
267
    if (typeof args !== 'object' || args === null) {
268
      return args;
269
    }
270
    if ('length' in args) { // array
271
      var simpleArgs = [], i, ii;
272
      var MAX_ITEMS = 10;
273
      for (i = 0, ii = Math.min(MAX_ITEMS, args.length); i < ii; i++) {
274
        simpleArgs.push(simplifyArgs(args[i]));
275
      }
276
      if (i < args.length) {
277
        simpleArgs.push('...');
278
      }
279
      return simpleArgs;
280
    }
281
    var simpleObj = {};
282
    for (var key in args) {
283
      simpleObj[key] = simplifyArgs(args[key]);
284
    }
285
    return simpleObj;
286
  }
287
288
  function Stepper(panel, pageIndex, initialBreakPoints) {
289
    this.panel = panel;
290
    this.breakPoint = 0;
291
    this.nextBreakPoint = null;
292
    this.pageIndex = pageIndex;
293
    this.breakPoints = initialBreakPoints;
294
    this.currentIdx = -1;
295
    this.operatorListIdx = 0;
296
  }
297
  Stepper.prototype = {
298
    init: function init(operatorList) {
299
      var panel = this.panel;
300
      var content = c('div', 'c=continue, s=step');
301
      var table = c('table');
302
      content.appendChild(table);
303
      table.cellSpacing = 0;
304
      var headerRow = c('tr');
305
      table.appendChild(headerRow);
306
      headerRow.appendChild(c('th', 'Break'));
307
      headerRow.appendChild(c('th', 'Idx'));
308
      headerRow.appendChild(c('th', 'fn'));
309
      headerRow.appendChild(c('th', 'args'));
310
      panel.appendChild(content);
311
      this.table = table;
312
      this.updateOperatorList(operatorList);
313
    },
314
    updateOperatorList: function updateOperatorList(operatorList) {
315
      var self = this;
316
317
      function cboxOnClick() {
318
        var x = +this.dataset.idx;
319
        if (this.checked) {
320
          self.breakPoints.push(x);
321
        } else {
322
          self.breakPoints.splice(self.breakPoints.indexOf(x), 1);
323
        }
324
        StepperManager.saveBreakPoints(self.pageIndex, self.breakPoints);
325
      }
326
327
      var MAX_OPERATORS_COUNT = 15000;
328
      if (this.operatorListIdx > MAX_OPERATORS_COUNT) {
329
        return;
330
      }
331
332
      var chunk = document.createDocumentFragment();
333
      var operatorsToDisplay = Math.min(MAX_OPERATORS_COUNT,
334
                                        operatorList.fnArray.length);
335
      for (var i = this.operatorListIdx; i < operatorsToDisplay; i++) {
336
        var line = c('tr');
337
        line.className = 'line';
338
        line.dataset.idx = i;
339
        chunk.appendChild(line);
340
        var checked = this.breakPoints.indexOf(i) !== -1;
341
        var args = operatorList.argsArray[i] || [];
342
343
        var breakCell = c('td');
344
        var cbox = c('input');
345
        cbox.type = 'checkbox';
346
        cbox.className = 'points';
347
        cbox.checked = checked;
348
        cbox.dataset.idx = i;
349
        cbox.onclick = cboxOnClick;
350
351
        breakCell.appendChild(cbox);
352
        line.appendChild(breakCell);
353
        line.appendChild(c('td', i.toString()));
354
        var fn = opMap[operatorList.fnArray[i]];
355
        var decArgs = args;
356
        if (fn === 'showText') {
357
          var glyphs = args[0];
358
          var newArgs = [];
359
          var str = [];
360
          for (var j = 0; j < glyphs.length; j++) {
361
            var glyph = glyphs[j];
362
            if (typeof glyph === 'object' && glyph !== null) {
363
              str.push(glyph.fontChar);
364
            } else {
365
              if (str.length > 0) {
366
                newArgs.push(str.join(''));
367
                str = [];
368
              }
369
              newArgs.push(glyph); // null or number
370
            }
371
          }
372
          if (str.length > 0) {
373
            newArgs.push(str.join(''));
374
          }
375
          decArgs = [newArgs];
376
        }
377
        line.appendChild(c('td', fn));
378
        line.appendChild(c('td', JSON.stringify(simplifyArgs(decArgs))));
379
      }
380
      if (operatorsToDisplay < operatorList.fnArray.length) {
381
        line = c('tr');
382
        var lastCell = c('td', '...');
383
        lastCell.colspan = 4;
384
        chunk.appendChild(lastCell);
385
      }
386
      this.operatorListIdx = operatorList.fnArray.length;
387
      this.table.appendChild(chunk);
388
    },
389
    getNextBreakPoint: function getNextBreakPoint() {
390
      this.breakPoints.sort(function(a, b) {
391
        return a - b;
392
      });
393
      for (var i = 0; i < this.breakPoints.length; i++) {
394
        if (this.breakPoints[i] > this.currentIdx) {
395
          return this.breakPoints[i];
396
        }
397
      }
398
      return null;
399
    },
400
    breakIt: function breakIt(idx, callback) {
401
      StepperManager.selectStepper(this.pageIndex, true);
402
      var self = this;
403
      var dom = document;
404
      self.currentIdx = idx;
405
      var listener = function(e) {
406
        switch (e.keyCode) {
407
          case 83: // step
408
            dom.removeEventListener('keydown', listener);
409
            self.nextBreakPoint = self.currentIdx + 1;
410
            self.goTo(-1);
411
            callback();
412
            break;
413
          case 67: // continue
414
            dom.removeEventListener('keydown', listener);
415
            var breakPoint = self.getNextBreakPoint();
416
            self.nextBreakPoint = breakPoint;
417
            self.goTo(-1);
418
            callback();
419
            break;
420
        }
421
      };
422
      dom.addEventListener('keydown', listener);
423
      self.goTo(idx);
424
    },
425
    goTo: function goTo(idx) {
426
      var allRows = this.panel.getElementsByClassName('line');
427
      for (var x = 0, xx = allRows.length; x < xx; ++x) {
428
        var row = allRows[x];
429
        if ((row.dataset.idx | 0) === idx) {
430
          row.style.backgroundColor = 'rgb(251,250,207)';
431
          row.scrollIntoView();
432
        } else {
433
          row.style.backgroundColor = null;
434
        }
435
      }
436
    },
437
  };
438
  return Stepper;
439
})();
440
441
var Stats = (function Stats() {
442
  var stats = [];
443
  function clear(node) {
444
    while (node.hasChildNodes()) {
445
      node.removeChild(node.lastChild);
446
    }
447
  }
448
  function getStatIndex(pageNumber) {
449
    for (var i = 0, ii = stats.length; i < ii; ++i) {
450
      if (stats[i].pageNumber === pageNumber) {
451
        return i;
452
      }
453
    }
454
    return false;
455
  }
456
  return {
457
    // Properties/functions needed by PDFBug.
458
    id: 'Stats',
459
    name: 'Stats',
460
    panel: null,
461
    manager: null,
462
    init(pdfjsLib) {
463
      this.panel.setAttribute('style', 'padding: 5px;');
464
      pdfjsLib.PDFJS.enableStats = true;
465
    },
466
    enabled: false,
467
    active: false,
468
    // Stats specific functions.
469
    add(pageNumber, stat) {
470
      if (!stat) {
471
        return;
472
      }
473
      var statsIndex = getStatIndex(pageNumber);
474
      if (statsIndex !== false) {
475
        var b = stats[statsIndex];
476
        this.panel.removeChild(b.div);
477
        stats.splice(statsIndex, 1);
478
      }
479
      var wrapper = document.createElement('div');
480
      wrapper.className = 'stats';
481
      var title = document.createElement('div');
482
      title.className = 'title';
483
      title.textContent = 'Page: ' + pageNumber;
484
      var statsDiv = document.createElement('div');
485
      statsDiv.textContent = stat.toString();
486
      wrapper.appendChild(title);
487
      wrapper.appendChild(statsDiv);
488
      stats.push({ pageNumber, div: wrapper, });
489
      stats.sort(function(a, b) {
490
        return a.pageNumber - b.pageNumber;
491
      });
492
      clear(this.panel);
493
      for (var i = 0, ii = stats.length; i < ii; ++i) {
494
        this.panel.appendChild(stats[i].div);
495
      }
496
    },
497
    cleanup() {
498
      stats = [];
499
      clear(this.panel);
500
    },
501
  };
502
})();
503
504
// Manages all the debugging tools.
505
window.PDFBug = (function PDFBugClosure() {
506
  var panelWidth = 300;
507
  var buttons = [];
508
  var activePanel = null;
509
510
  return {
511
    tools: [
512
      FontInspector,
513
      StepperManager,
514
      Stats
515
    ],
516
    enable(ids) {
517
      var all = false, tools = this.tools;
518
      if (ids.length === 1 && ids[0] === 'all') {
519
        all = true;
520
      }
521
      for (var i = 0; i < tools.length; ++i) {
522
        var tool = tools[i];
523
        if (all || ids.indexOf(tool.id) !== -1) {
524
          tool.enabled = true;
525
        }
526
      }
527
      if (!all) {
528
        // Sort the tools by the order they are enabled.
529
        tools.sort(function(a, b) {
530
          var indexA = ids.indexOf(a.id);
531
          indexA = indexA < 0 ? tools.length : indexA;
532
          var indexB = ids.indexOf(b.id);
533
          indexB = indexB < 0 ? tools.length : indexB;
534
          return indexA - indexB;
535
        });
536
      }
537
    },
538
    init(pdfjsLib, container) {
539
      /*
540
       * Basic Layout:
541
       * PDFBug
542
       *  Controls
543
       *  Panels
544
       *    Panel
545
       *    Panel
546
       *    ...
547
       */
548
      var ui = document.createElement('div');
549
      ui.id = 'PDFBug';
550
551
      var controls = document.createElement('div');
552
      controls.setAttribute('class', 'controls');
553
      ui.appendChild(controls);
554
555
      var panels = document.createElement('div');
556
      panels.setAttribute('class', 'panels');
557
      ui.appendChild(panels);
558
559
      container.appendChild(ui);
560
      container.style.right = panelWidth + 'px';
561
562
      // Initialize all the debugging tools.
563
      var tools = this.tools;
564
      var self = this;
565
      for (var i = 0; i < tools.length; ++i) {
566
        var tool = tools[i];
567
        var panel = document.createElement('div');
568
        var panelButton = document.createElement('button');
569
        panelButton.textContent = tool.name;
570
        panelButton.addEventListener('click', (function(selected) {
571
          return function(event) {
572
            event.preventDefault();
573
            self.selectPanel(selected);
574
          };
575
        })(i));
576
        controls.appendChild(panelButton);
577
        panels.appendChild(panel);
578
        tool.panel = panel;
579
        tool.manager = this;
580
        if (tool.enabled) {
581
          tool.init(pdfjsLib);
582
        } else {
583
          panel.textContent = tool.name + ' is disabled. To enable add ' +
584
                              ' "' + tool.id + '" to the pdfBug parameter ' +
585
                              'and refresh (separate multiple by commas).';
586
        }
587
        buttons.push(panelButton);
588
      }
589
      this.selectPanel(0);
590
    },
591
    cleanup() {
592
      for (var i = 0, ii = this.tools.length; i < ii; i++) {
593
        if (this.tools[i].enabled) {
594
          this.tools[i].cleanup();
595
        }
596
      }
597
    },
598
    selectPanel(index) {
599
      if (typeof index !== 'number') {
600
        index = this.tools.indexOf(index);
601
      }
602
      if (index === activePanel) {
603
        return;
604
      }
605
      activePanel = index;
606
      var tools = this.tools;
607
      for (var j = 0; j < tools.length; ++j) {
608
        if (j === index) {
609
          buttons[j].setAttribute('class', 'active');
610
          tools[j].active = true;
611
          tools[j].panel.removeAttribute('hidden');
612
        } else {
613
          buttons[j].setAttribute('class', '');
614
          tools[j].active = false;
615
          tools[j].panel.setAttribute('hidden', 'true');
616
        }
617
      }
618
    },
619
  };
620
})();
621