Issues (1495)

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.

laraview/ui_utils.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
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* Copyright 2012 Mozilla Foundation
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
'use strict';
18
19
var CSS_UNITS = 96.0 / 72.0;
20
var DEFAULT_SCALE = 'auto';
21
var UNKNOWN_SCALE = 0;
22
var MAX_AUTO_SCALE = 1.25;
23
var SCROLLBAR_PADDING = 40;
24
var VERTICAL_PADDING = 5;
25
26
// optimised CSS custom property getter/setter
27
var CustomStyle = (function CustomStyleClosure() {
28
29
  // As noted on: http://www.zachstronaut.com/posts/2009/02/17/
30
  //              animate-css-transforms-firefox-webkit.html
31
  // in some versions of IE9 it is critical that ms appear in this list
32
  // before Moz
33
  var prefixes = ['ms', 'Moz', 'Webkit', 'O'];
34
  var _cache = {};
35
36
  function CustomStyle() {}
37
38
  CustomStyle.getProp = function get(propName, element) {
39
    // check cache only when no element is given
40
    if (arguments.length === 1 && typeof _cache[propName] === 'string') {
41
      return _cache[propName];
42
    }
43
44
    element = element || document.documentElement;
45
    var style = element.style, prefixed, uPropName;
46
47
    // test standard property first
48
    if (typeof style[propName] === 'string') {
49
      return (_cache[propName] = propName);
50
    }
51
52
    // capitalize
53
    uPropName = propName.charAt(0).toUpperCase() + propName.slice(1);
54
55
    // test vendor specific properties
56
    for (var i = 0, l = prefixes.length; i < l; i++) {
57
      prefixed = prefixes[i] + uPropName;
58
      if (typeof style[prefixed] === 'string') {
59
        return (_cache[propName] = prefixed);
60
      }
61
    }
62
63
    //if all fails then set to undefined
64
    return (_cache[propName] = 'undefined');
65
  };
66
67
  CustomStyle.setProp = function set(propName, element, str) {
68
    var prop = this.getProp(propName);
69
    if (prop !== 'undefined') {
70
      element.style[prop] = str;
71
    }
72
  };
73
74
  return CustomStyle;
75
})();
76
77
function getFileName(url) {
78
  var anchor = url.indexOf('#');
79
  var query = url.indexOf('?');
80
  var end = Math.min(
81
    anchor > 0 ? anchor : url.length,
82
    query > 0 ? query : url.length);
83
  return url.substring(url.lastIndexOf('/', end) + 1, end);
84
}
85
86
/**
87
 * Returns scale factor for the canvas. It makes sense for the HiDPI displays.
88
 * @return {Object} The object with horizontal (sx) and vertical (sy)
89
                    scales. The scaled property is set to false if scaling is
90
                    not required, true otherwise.
91
 */
92
function getOutputScale(ctx) {
93
  var devicePixelRatio = window.devicePixelRatio || 1;
94
  var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
95
                          ctx.mozBackingStorePixelRatio ||
96
                          ctx.msBackingStorePixelRatio ||
97
                          ctx.oBackingStorePixelRatio ||
98
                          ctx.backingStorePixelRatio || 1;
99
  var pixelRatio = devicePixelRatio / backingStoreRatio;
100
  return {
101
    sx: pixelRatio,
102
    sy: pixelRatio,
103
    scaled: pixelRatio !== 1
104
  };
105
}
106
107
/**
108
 * Scrolls specified element into view of its parent.
109
 * element {Object} The element to be visible.
110
 * spot {Object} An object with optional top and left properties,
111
 *               specifying the offset from the top left edge.
112
 */
113
function scrollIntoView(element, spot) {
114
  // Assuming offsetParent is available (it's not available when viewer is in
115
  // hidden iframe or object). We have to scroll: if the offsetParent is not set
116
  // producing the error. See also animationStartedClosure.
117
  var parent = element.offsetParent;
118
  var offsetY = element.offsetTop + element.clientTop;
119
  var offsetX = element.offsetLeft + element.clientLeft;
120
  if (!parent) {
121
    console.error('offsetParent is not set -- cannot scroll');
122
    return;
123
  }
124
  while (parent.clientHeight === parent.scrollHeight) {
125
    if (parent.dataset._scaleY) {
126
      offsetY /= parent.dataset._scaleY;
127
      offsetX /= parent.dataset._scaleX;
128
    }
129
    offsetY += parent.offsetTop;
130
    offsetX += parent.offsetLeft;
131
    parent = parent.offsetParent;
132
    if (!parent) {
133
      return; // no need to scroll
134
    }
135
  }
136
  if (spot) {
137
    if (spot.top !== undefined) {
138
      offsetY += spot.top;
139
    }
140
    if (spot.left !== undefined) {
141
      offsetX += spot.left;
142
      parent.scrollLeft = offsetX;
143
    }
144
  }
145
  parent.scrollTop = offsetY;
146
}
147
148
/**
149
 * Helper function to start monitoring the scroll event and converting them into
150
 * PDF.js friendly one: with scroll debounce and scroll direction.
151
 */
152
function watchScroll(viewAreaElement, callback) {
153
  var debounceScroll = function debounceScroll(evt) {
0 ignored issues
show
The parameter evt is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Comprehensibility Naming Best Practice introduced by
The variable debounceScroll already seems to be declared on line 153. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
154
    if (rAF) {
155
      return;
156
    }
157
    // schedule an invocation of scroll for next animation frame.
158
    rAF = window.requestAnimationFrame(function viewAreaElementScrolled() {
159
      rAF = null;
160
161
      var currentY = viewAreaElement.scrollTop;
162
      var lastY = state.lastY;
163
      if (currentY !== lastY) {
164
        state.down = currentY > lastY;
165
      }
166
      state.lastY = currentY;
167
      callback(state);
168
    });
169
  };
170
171
  var state = {
172
    down: true,
173
    lastY: viewAreaElement.scrollTop,
174
    _eventHandler: debounceScroll
175
  };
176
177
  var rAF = null;
178
  viewAreaElement.addEventListener('scroll', debounceScroll, true);
179
  return state;
180
}
181
182
/**
183
 * Use binary search to find the index of the first item in a given array which
184
 * passes a given condition. The items are expected to be sorted in the sense
185
 * that if the condition is true for one item in the array, then it is also true
186
 * for all following items.
187
 *
188
 * @returns {Number} Index of the first array element to pass the test,
189
 *                   or |items.length| if no such element exists.
190
 */
191
function binarySearchFirstItem(items, condition) {
192
  var minIndex = 0;
193
  var maxIndex = items.length - 1;
194
195
  if (items.length === 0 || !condition(items[maxIndex])) {
196
    return items.length;
197
  }
198
  if (condition(items[minIndex])) {
199
    return minIndex;
200
  }
201
202
  while (minIndex < maxIndex) {
203
    var currentIndex = (minIndex + maxIndex) >> 1;
204
    var currentItem = items[currentIndex];
205
    if (condition(currentItem)) {
206
      maxIndex = currentIndex;
207
    } else {
208
      minIndex = currentIndex + 1;
209
    }
210
  }
211
  return minIndex; /* === maxIndex */
212
}
213
214
/**
215
 * Generic helper to find out what elements are visible within a scroll pane.
216
 */
217
function getVisibleElements(scrollEl, views, sortByVisibility) {
218
  var top = scrollEl.scrollTop, bottom = top + scrollEl.clientHeight;
219
  var left = scrollEl.scrollLeft, right = left + scrollEl.clientWidth;
220
221
  function isElementBottomBelowViewTop(view) {
222
    var element = view.div;
223
    var elementBottom =
224
      element.offsetTop + element.clientTop + element.clientHeight;
225
    return elementBottom > top;
226
  }
227
228
  var visible = [], view, element;
229
  var currentHeight, viewHeight, hiddenHeight, percentHeight;
230
  var currentWidth, viewWidth;
231
  var firstVisibleElementInd = (views.length === 0) ? 0 :
232
    binarySearchFirstItem(views, isElementBottomBelowViewTop);
233
234
  for (var i = firstVisibleElementInd, ii = views.length; i < ii; i++) {
235
    view = views[i];
236
    element = view.div;
237
    currentHeight = element.offsetTop + element.clientTop;
238
    viewHeight = element.clientHeight;
239
240
    if (currentHeight > bottom) {
241
      break;
242
    }
243
244
    currentWidth = element.offsetLeft + element.clientLeft;
245
    viewWidth = element.clientWidth;
246
    if (currentWidth + viewWidth < left || currentWidth > right) {
247
      continue;
248
    }
249
    hiddenHeight = Math.max(0, top - currentHeight) +
250
      Math.max(0, currentHeight + viewHeight - bottom);
251
    percentHeight = ((viewHeight - hiddenHeight) * 100 / viewHeight) | 0;
252
253
    visible.push({
254
      id: view.id,
255
      x: currentWidth,
256
      y: currentHeight,
257
      view: view,
258
      percent: percentHeight
259
    });
260
  }
261
262
  var first = visible[0];
263
  var last = visible[visible.length - 1];
264
265
  if (sortByVisibility) {
266
    visible.sort(function(a, b) {
267
      var pc = a.percent - b.percent;
268
      if (Math.abs(pc) > 0.001) {
269
        return -pc;
270
      }
271
      return a.id - b.id; // ensure stability
272
    });
273
  }
274
  return {first: first, last: last, views: visible};
275
}
276
277
/**
278
 * Event handler to suppress context menu.
279
 */
280
function noContextMenuHandler(e) {
281
  e.preventDefault();
282
}
283
284
/**
285
 * Returns the filename or guessed filename from the url (see issue 3455).
286
 * url {String} The original PDF location.
287
 * @return {String} Guessed PDF file name.
288
 */
289
function getPDFFileNameFromURL(url) {
290
  var reURI = /^(?:([^:]+:)?\/\/[^\/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
291
  //            SCHEME      HOST         1.PATH  2.QUERY   3.REF
292
  // Pattern to get last matching NAME.pdf
293
  var reFilename = /[^\/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
294
  var splitURI = reURI.exec(url);
295
  var suggestedFilename = reFilename.exec(splitURI[1]) ||
296
                           reFilename.exec(splitURI[2]) ||
297
                           reFilename.exec(splitURI[3]);
298
  if (suggestedFilename) {
299
    suggestedFilename = suggestedFilename[0];
300
    if (suggestedFilename.indexOf('%') !== -1) {
301
      // URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
302
      try {
303
        suggestedFilename =
304
          reFilename.exec(decodeURIComponent(suggestedFilename))[0];
305
      } catch(e) { // Possible (extremely rare) errors:
306
        // URIError "Malformed URI", e.g. for "%AA.pdf"
307
        // TypeError "null has no properties", e.g. for "%2F.pdf"
308
      }
309
    }
310
  }
311
  return suggestedFilename || 'document.pdf';
312
}
313
314
var ProgressBar = (function ProgressBarClosure() {
315
316
  function clamp(v, min, max) {
317
    return Math.min(Math.max(v, min), max);
318
  }
319
320
  function ProgressBar(id, opts) {
321
    this.visible = true;
322
323
    // Fetch the sub-elements for later.
324
    this.div = document.querySelector(id + ' .progress');
325
326
    // Get the loading bar element, so it can be resized to fit the viewer.
327
    this.bar = this.div.parentNode;
328
329
    // Get options, with sensible defaults.
330
    this.height = opts.height || 100;
331
    this.width = opts.width || 100;
332
    this.units = opts.units || '%';
333
334
    // Initialize heights.
335
    this.div.style.height = this.height + this.units;
336
    this.percent = 0;
337
  }
338
339
  ProgressBar.prototype = {
340
341
    updateBar: function ProgressBar_updateBar() {
342
      if (this._indeterminate) {
343
        this.div.classList.add('indeterminate');
344
        this.div.style.width = this.width + this.units;
345
        return;
346
      }
347
348
      this.div.classList.remove('indeterminate');
349
      var progressSize = this.width * this._percent / 100;
350
      this.div.style.width = progressSize + this.units;
351
    },
352
353
    get percent() {
354
      return this._percent;
355
    },
356
357
    set percent(val) {
358
      this._indeterminate = isNaN(val);
359
      this._percent = clamp(val, 0, 100);
360
      this.updateBar();
361
    },
362
363
    setWidth: function ProgressBar_setWidth(viewer) {
364
      if (viewer) {
365
        var container = viewer.parentNode;
366
        var scrollbarWidth = container.offsetWidth - viewer.offsetWidth;
367
        if (scrollbarWidth > 0) {
368
          this.bar.setAttribute('style', 'width: calc(100% - ' +
369
                                         scrollbarWidth + 'px);');
370
        }
371
      }
372
    },
373
374
    hide: function ProgressBar_hide() {
375
      if (!this.visible) {
376
        return;
377
      }
378
      this.visible = false;
379
      this.bar.classList.add('hidden');
380
      document.body.classList.remove('loadingInProgress');
381
    },
382
383
    show: function ProgressBar_show() {
384
      if (this.visible) {
385
        return;
386
      }
387
      this.visible = true;
388
      document.body.classList.add('loadingInProgress');
389
      this.bar.classList.remove('hidden');
390
    }
391
  };
392
393
  return ProgressBar;
394
})();
395